1167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org// Copyright 2008, Google Inc.
2167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org// All rights reserved.
3167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org//
4167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org// Redistribution and use in source and binary forms, with or without
5167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org// modification, are permitted provided that the following conditions are
6167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org// met:
7167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org//
8167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org//     * Redistributions of source code must retain the above copyright
9167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org// notice, this list of conditions and the following disclaimer.
10167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org//     * Redistributions in binary form must reproduce the above
11167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org// copyright notice, this list of conditions and the following disclaimer
12167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org// in the documentation and/or other materials provided with the
13167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org// distribution.
14167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org//     * Neither the name of Google Inc. nor the names of its
15167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org// contributors may be used to endorse or promote products derived from
16167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org// this software without specific prior written permission.
17167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org//
18167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org//
30167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org// Author: mheule@google.com (Markus Heule)
31167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org//
32167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org// Google C++ Testing Framework (Google Test)
33167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org//
34167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org// Sometimes it's desirable to build Google Test by compiling a single file.
35167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org// This file serves this purpose.
36167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org
37167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org// This line ensures that gtest.h can be compiled on its own, even
38167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org// when it's fused.
39167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org#include "gtest/gtest.h"
40167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org
41167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org// The following lines pull in the real gtest *.cc files.
420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Copyright 2005, Google Inc.
430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// All rights reserved.
440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Redistribution and use in source and binary forms, with or without
460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// modification, are permitted provided that the following conditions are
470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// met:
480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//     * Redistributions of source code must retain the above copyright
500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// notice, this list of conditions and the following disclaimer.
510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//     * Redistributions in binary form must reproduce the above
520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// copyright notice, this list of conditions and the following disclaimer
530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// in the documentation and/or other materials provided with the
540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// distribution.
550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//     * Neither the name of Google Inc. nor the names of its
560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// contributors may be used to endorse or promote products derived from
570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// this software without specific prior written permission.
580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Author: wan@google.com (Zhanyong Wan)
720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// The Google C++ Testing Framework (Google Test)
740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Copyright 2007, Google Inc.
760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// All rights reserved.
770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Redistribution and use in source and binary forms, with or without
790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// modification, are permitted provided that the following conditions are
800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// met:
810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//     * Redistributions of source code must retain the above copyright
830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// notice, this list of conditions and the following disclaimer.
840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//     * Redistributions in binary form must reproduce the above
850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// copyright notice, this list of conditions and the following disclaimer
860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// in the documentation and/or other materials provided with the
870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// distribution.
880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//     * Neither the name of Google Inc. nor the names of its
890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// contributors may be used to endorse or promote products derived from
900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// this software without specific prior written permission.
910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
1000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
1020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
1040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Author: wan@google.com (Zhanyong Wan)
1050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
1060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Utilities for testing Google Test itself and code that uses Google Test
1070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// (e.g. frameworks built on top of Google Test).
1080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
1090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#ifndef GTEST_INCLUDE_GTEST_GTEST_SPI_H_
1100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#define GTEST_INCLUDE_GTEST_GTEST_SPI_H_
1110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
1120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
1130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgnamespace testing {
1140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
1150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// This helper class can be used to mock out Google Test failure reporting
1160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// so that we can test Google Test or code that builds on Google Test.
1170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
1180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// An object of this class appends a TestPartResult object to the
1190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// TestPartResultArray object given in the constructor whenever a Google Test
1200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// failure is reported. It can either intercept only failures that are
1210d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// generated in the same thread that created this object or it can intercept
1220d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// all generated failures. The scope of this mock object can be controlled with
1230d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// the second argument to the two arguments constructor.
1240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgclass GTEST_API_ ScopedFakeTestPartResultReporter
1250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    : public TestPartResultReporterInterface {
1260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org public:
1270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // The two possible mocking modes of this object.
1280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  enum InterceptMode {
1290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    INTERCEPT_ONLY_CURRENT_THREAD,  // Intercepts only thread local failures.
1300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    INTERCEPT_ALL_THREADS           // Intercepts all failures.
1310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  };
1320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
1330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // The c'tor sets this object as the test part result reporter used
1340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // by Google Test.  The 'result' parameter specifies where to report the
1350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // results. This reporter will only catch failures generated in the current
1360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // thread. DEPRECATED
1370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  explicit ScopedFakeTestPartResultReporter(TestPartResultArray* result);
1380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
1390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Same as above, but you can choose the interception scope of this object.
1400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  ScopedFakeTestPartResultReporter(InterceptMode intercept_mode,
1410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                   TestPartResultArray* result);
1420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
1430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // The d'tor restores the previous test part result reporter.
1440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  virtual ~ScopedFakeTestPartResultReporter();
1450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
1460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Appends the TestPartResult object to the TestPartResultArray
1470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // received in the constructor.
1480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  //
1490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // This method is from the TestPartResultReporterInterface
1500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // interface.
1510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  virtual void ReportTestPartResult(const TestPartResult& result);
1520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org private:
1530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  void Init();
1540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
1550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const InterceptMode intercept_mode_;
1560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  TestPartResultReporterInterface* old_reporter_;
1570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  TestPartResultArray* const result_;
1580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
1590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  GTEST_DISALLOW_COPY_AND_ASSIGN_(ScopedFakeTestPartResultReporter);
1600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org};
1610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
1620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgnamespace internal {
1630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
1640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// A helper class for implementing EXPECT_FATAL_FAILURE() and
1650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// EXPECT_NONFATAL_FAILURE().  Its destructor verifies that the given
1660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// TestPartResultArray contains exactly one failure that has the given
1670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// type and contains the given substring.  If that's not the case, a
1680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// non-fatal failure will be generated.
1690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgclass GTEST_API_ SingleFailureChecker {
1700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org public:
1710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // The constructor remembers the arguments.
1720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  SingleFailureChecker(const TestPartResultArray* results,
1730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                       TestPartResult::Type type,
1740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                       const string& substr);
1750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  ~SingleFailureChecker();
1760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org private:
1770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const TestPartResultArray* const results_;
1780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const TestPartResult::Type type_;
1790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const string substr_;
1800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
1810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  GTEST_DISALLOW_COPY_AND_ASSIGN_(SingleFailureChecker);
1820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org};
1830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
1840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}  // namespace internal
1850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
1860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}  // namespace testing
1870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
1880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// A set of macros for testing Google Test assertions or code that's expected
1890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// to generate Google Test fatal failures.  It verifies that the given
1900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// statement will cause exactly one fatal Google Test failure with 'substr'
1910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// being part of the failure message.
1920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
1930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// There are two different versions of this macro. EXPECT_FATAL_FAILURE only
1940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// affects and considers failures generated in the current thread and
1950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// EXPECT_FATAL_FAILURE_ON_ALL_THREADS does the same but for all threads.
1960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
1970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// The verification of the assertion is done correctly even when the statement
1980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// throws an exception or aborts the current function.
1990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
2000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Known restrictions:
2010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//   - 'statement' cannot reference local non-static variables or
2020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//     non-static members of the current object.
2030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//   - 'statement' cannot return a value.
2040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//   - You cannot stream a failure message to this macro.
2050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
2060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Note that even though the implementations of the following two
2070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// macros are much alike, we cannot refactor them to use a common
2080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// helper macro, due to some peculiarity in how the preprocessor
2090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// works.  The AcceptsMacroThatExpandsToUnprotectedComma test in
2100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// gtest_unittest.cc will fail to compile if we do that.
2110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#define EXPECT_FATAL_FAILURE(statement, substr) \
2120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  do { \
2130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    class GTestExpectFatalFailureHelper {\
2140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org     public:\
2150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      static void Execute() { statement; }\
2160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    };\
2170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    ::testing::TestPartResultArray gtest_failures;\
2180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    ::testing::internal::SingleFailureChecker gtest_checker(\
2190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        &gtest_failures, ::testing::TestPartResult::kFatalFailure, (substr));\
2200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    {\
2210d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\
2220d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          ::testing::ScopedFakeTestPartResultReporter:: \
2230d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          INTERCEPT_ONLY_CURRENT_THREAD, &gtest_failures);\
2240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      GTestExpectFatalFailureHelper::Execute();\
2250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    }\
2260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  } while (::testing::internal::AlwaysFalse())
2270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
2280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#define EXPECT_FATAL_FAILURE_ON_ALL_THREADS(statement, substr) \
2290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  do { \
2300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    class GTestExpectFatalFailureHelper {\
2310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org     public:\
2320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      static void Execute() { statement; }\
2330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    };\
2340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    ::testing::TestPartResultArray gtest_failures;\
2350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    ::testing::internal::SingleFailureChecker gtest_checker(\
2360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        &gtest_failures, ::testing::TestPartResult::kFatalFailure, (substr));\
2370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    {\
2380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\
2390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          ::testing::ScopedFakeTestPartResultReporter:: \
2400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          INTERCEPT_ALL_THREADS, &gtest_failures);\
2410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      GTestExpectFatalFailureHelper::Execute();\
2420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    }\
2430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  } while (::testing::internal::AlwaysFalse())
2440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
2450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// A macro for testing Google Test assertions or code that's expected to
2460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// generate Google Test non-fatal failures.  It asserts that the given
2470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// statement will cause exactly one non-fatal Google Test failure with 'substr'
2480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// being part of the failure message.
2490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
2500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// There are two different versions of this macro. EXPECT_NONFATAL_FAILURE only
2510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// affects and considers failures generated in the current thread and
2520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS does the same but for all threads.
2530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
2540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// 'statement' is allowed to reference local variables and members of
2550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// the current object.
2560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
2570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// The verification of the assertion is done correctly even when the statement
2580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// throws an exception or aborts the current function.
2590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
2600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Known restrictions:
2610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//   - You cannot stream a failure message to this macro.
2620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
2630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Note that even though the implementations of the following two
2640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// macros are much alike, we cannot refactor them to use a common
2650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// helper macro, due to some peculiarity in how the preprocessor
2660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// works.  If we do that, the code won't compile when the user gives
2670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// EXPECT_NONFATAL_FAILURE() a statement that contains a macro that
2680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// expands to code containing an unprotected comma.  The
2690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// AcceptsMacroThatExpandsToUnprotectedComma test in gtest_unittest.cc
2700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// catches that.
2710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
2720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// For the same reason, we have to write
2730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//   if (::testing::internal::AlwaysTrue()) { statement; }
2740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// instead of
2750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//   GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement)
2760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// to avoid an MSVC warning on unreachable code.
2770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#define EXPECT_NONFATAL_FAILURE(statement, substr) \
2780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  do {\
2790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    ::testing::TestPartResultArray gtest_failures;\
2800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    ::testing::internal::SingleFailureChecker gtest_checker(\
2810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        &gtest_failures, ::testing::TestPartResult::kNonFatalFailure, \
2820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        (substr));\
2830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    {\
2840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\
2850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          ::testing::ScopedFakeTestPartResultReporter:: \
2860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          INTERCEPT_ONLY_CURRENT_THREAD, &gtest_failures);\
2870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      if (::testing::internal::AlwaysTrue()) { statement; }\
2880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    }\
2890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  } while (::testing::internal::AlwaysFalse())
2900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
2910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#define EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(statement, substr) \
2920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  do {\
2930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    ::testing::TestPartResultArray gtest_failures;\
2940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    ::testing::internal::SingleFailureChecker gtest_checker(\
2950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        &gtest_failures, ::testing::TestPartResult::kNonFatalFailure, \
2960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        (substr));\
2970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    {\
2980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\
2990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          ::testing::ScopedFakeTestPartResultReporter::INTERCEPT_ALL_THREADS, \
3000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          &gtest_failures);\
3010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      if (::testing::internal::AlwaysTrue()) { statement; }\
3020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    }\
3030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  } while (::testing::internal::AlwaysFalse())
3040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
3050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#endif  // GTEST_INCLUDE_GTEST_GTEST_SPI_H_
3060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
3070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#include <ctype.h>
3080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#include <math.h>
3090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#include <stdarg.h>
3100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#include <stdio.h>
3110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#include <stdlib.h>
3120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#include <time.h>
3130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#include <wchar.h>
3140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#include <wctype.h>
3150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
3160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#include <algorithm>
3170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#include <iomanip>
3180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#include <limits>
3190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#include <ostream>  // NOLINT
3200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#include <sstream>
3210d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#include <vector>
3220d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
3230d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#if GTEST_OS_LINUX
3240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
3250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// TODO(kenton@google.com): Use autoconf to detect availability of
3260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// gettimeofday().
3270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# define GTEST_HAS_GETTIMEOFDAY_ 1
3280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
3290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# include <fcntl.h>  // NOLINT
3300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# include <limits.h>  // NOLINT
3310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# include <sched.h>  // NOLINT
3320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Declares vsnprintf().  This header is not available on Windows.
3330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# include <strings.h>  // NOLINT
3340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# include <sys/mman.h>  // NOLINT
3350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# include <sys/time.h>  // NOLINT
3360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# include <unistd.h>  // NOLINT
3370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# include <string>
3380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
3390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#elif GTEST_OS_SYMBIAN
3400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# define GTEST_HAS_GETTIMEOFDAY_ 1
3410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# include <sys/time.h>  // NOLINT
3420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
3430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#elif GTEST_OS_ZOS
3440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# define GTEST_HAS_GETTIMEOFDAY_ 1
3450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# include <sys/time.h>  // NOLINT
3460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
3470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// On z/OS we additionally need strings.h for strcasecmp.
3480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# include <strings.h>  // NOLINT
3490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
3500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#elif GTEST_OS_WINDOWS_MOBILE  // We are on Windows CE.
3510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
3520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# include <windows.h>  // NOLINT
3530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
3540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#elif GTEST_OS_WINDOWS  // We are on Windows proper.
3550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
3560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# include <io.h>  // NOLINT
3570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# include <sys/timeb.h>  // NOLINT
3580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# include <sys/types.h>  // NOLINT
3590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# include <sys/stat.h>  // NOLINT
3600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
3610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# if GTEST_OS_WINDOWS_MINGW
3620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// MinGW has gettimeofday() but not _ftime64().
3630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// TODO(kenton@google.com): Use autoconf to detect availability of
3640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//   gettimeofday().
3650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// TODO(kenton@google.com): There are other ways to get the time on
3660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//   Windows, like GetTickCount() or GetSystemTimeAsFileTime().  MinGW
3670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//   supports these.  consider using them instead.
3680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#  define GTEST_HAS_GETTIMEOFDAY_ 1
3690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#  include <sys/time.h>  // NOLINT
3700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# endif  // GTEST_OS_WINDOWS_MINGW
3710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
3720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// cpplint thinks that the header is already included, so we want to
3730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// silence it.
3740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# include <windows.h>  // NOLINT
3750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
3760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#else
3770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
3780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Assume other platforms have gettimeofday().
3790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// TODO(kenton@google.com): Use autoconf to detect availability of
3800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//   gettimeofday().
3810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# define GTEST_HAS_GETTIMEOFDAY_ 1
3820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
3830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// cpplint thinks that the header is already included, so we want to
3840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// silence it.
3850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# include <sys/time.h>  // NOLINT
3860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# include <unistd.h>  // NOLINT
3870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
3880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#endif  // GTEST_OS_LINUX
3890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
3900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#if GTEST_HAS_EXCEPTIONS
3910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# include <stdexcept>
3920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#endif
3930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
3940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#if GTEST_CAN_STREAM_RESULTS_
3950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# include <arpa/inet.h>  // NOLINT
3960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# include <netdb.h>  // NOLINT
3970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#endif
3980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
3990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Indicates that this translation unit is part of Google Test's
4000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// implementation.  It must come before gtest-internal-inl.h is
4010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// included, or there will be a compiler error.  This trick is to
4020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// prevent a user from accidentally including gtest-internal-inl.h in
4030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// his code.
4040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#define GTEST_IMPLEMENTATION_ 1
4050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Copyright 2005, Google Inc.
4060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// All rights reserved.
4070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
4080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Redistribution and use in source and binary forms, with or without
4090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// modification, are permitted provided that the following conditions are
4100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// met:
4110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
4120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//     * Redistributions of source code must retain the above copyright
4130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// notice, this list of conditions and the following disclaimer.
4140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//     * Redistributions in binary form must reproduce the above
4150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// copyright notice, this list of conditions and the following disclaimer
4160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// in the documentation and/or other materials provided with the
4170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// distribution.
4180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//     * Neither the name of Google Inc. nor the names of its
4190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// contributors may be used to endorse or promote products derived from
4200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// this software without specific prior written permission.
4210d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
4220d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
4230d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
4240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
4250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
4260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
4270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
4280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
4290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
4300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
4310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
4320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
4340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Utility functions and classes used by the Google C++ testing framework.
4350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
4360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Author: wan@google.com (Zhanyong Wan)
4370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
4380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// This file contains purely Google Test's internal implementation.  Please
4390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// DO NOT #INCLUDE IT IN A USER PROGRAM.
4400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
4410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#ifndef GTEST_SRC_GTEST_INTERNAL_INL_H_
4420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#define GTEST_SRC_GTEST_INTERNAL_INL_H_
4430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
4440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// GTEST_IMPLEMENTATION_ is defined to 1 iff the current translation unit is
4450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// part of Google Test's implementation; otherwise it's undefined.
4460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#if !GTEST_IMPLEMENTATION_
4470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// A user is trying to include this from his code - just say no.
4480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# error "gtest-internal-inl.h is part of Google Test's internal implementation."
4490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# error "It must not be included except by Google Test itself."
4500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#endif  // GTEST_IMPLEMENTATION_
4510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
4520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#ifndef _WIN32_WCE
4530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# include <errno.h>
4540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#endif  // !_WIN32_WCE
4550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#include <stddef.h>
4560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#include <stdlib.h>  // For strtoll/_strtoul64/malloc/free.
4570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#include <string.h>  // For memmove.
4580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
4590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#include <algorithm>
4600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#include <string>
4610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#include <vector>
4620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
4630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
4640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#if GTEST_CAN_STREAM_RESULTS_
4650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# include <arpa/inet.h>  // NOLINT
4660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# include <netdb.h>  // NOLINT
4670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#endif
4680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
4690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#if GTEST_OS_WINDOWS
4700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# include <windows.h>  // NOLINT
4710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#endif  // GTEST_OS_WINDOWS
4720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
4730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
4740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgnamespace testing {
4750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
4760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Declares the flags.
4770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
4780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// We don't want the users to modify this flag in the code, but want
4790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Google Test's own unit tests to be able to access it. Therefore we
4800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// declare it here as opposed to in gtest.h.
4810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgGTEST_DECLARE_bool_(death_test_use_fork);
4820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
4830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgnamespace internal {
4840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
4850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// The value of GetTestTypeId() as seen from within the Google Test
4860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// library.  This is solely for testing GetTestTypeId().
4870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgGTEST_API_ extern const TypeId kTestTypeIdInGoogleTest;
4880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
4890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Names of the flags (needed for parsing Google Test flags).
4900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgconst char kAlsoRunDisabledTestsFlag[] = "also_run_disabled_tests";
4910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgconst char kBreakOnFailureFlag[] = "break_on_failure";
4920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgconst char kCatchExceptionsFlag[] = "catch_exceptions";
4930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgconst char kColorFlag[] = "color";
4940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgconst char kFilterFlag[] = "filter";
4950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgconst char kListTestsFlag[] = "list_tests";
4960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgconst char kOutputFlag[] = "output";
4970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgconst char kPrintTimeFlag[] = "print_time";
4980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgconst char kRandomSeedFlag[] = "random_seed";
4990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgconst char kRepeatFlag[] = "repeat";
5000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgconst char kShuffleFlag[] = "shuffle";
5010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgconst char kStackTraceDepthFlag[] = "stack_trace_depth";
5020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgconst char kStreamResultToFlag[] = "stream_result_to";
5030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgconst char kThrowOnFailureFlag[] = "throw_on_failure";
5040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
5050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// A valid random seed must be in [1, kMaxRandomSeed].
5060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgconst int kMaxRandomSeed = 99999;
5070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
5080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// g_help_flag is true iff the --help flag or an equivalent form is
5090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// specified on the command line.
5100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgGTEST_API_ extern bool g_help_flag;
5110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
5120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Returns the current time in milliseconds.
5130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgGTEST_API_ TimeInMillis GetTimeInMillis();
5140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
5150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Returns true iff Google Test should use colors in the output.
5160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgGTEST_API_ bool ShouldUseColor(bool stdout_is_tty);
5170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
5180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Formats the given time in milliseconds as seconds.
5190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgGTEST_API_ std::string FormatTimeInMillisAsSeconds(TimeInMillis ms);
5200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
5210d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Converts the given time in milliseconds to a date string in the ISO 8601
5220d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// format, without the timezone information.  N.B.: due to the use the
5230d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// non-reentrant localtime() function, this function is not thread safe.  Do
5240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// not use it in any code that can be called from multiple threads.
5250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgGTEST_API_ std::string FormatEpochTimeInMillisAsIso8601(TimeInMillis ms);
5260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
5270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Parses a string for an Int32 flag, in the form of "--flag=value".
5280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
5290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// On success, stores the value of the flag in *value, and returns
5300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// true.  On failure, returns false without changing *value.
5310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgGTEST_API_ bool ParseInt32Flag(
5320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const char* str, const char* flag, Int32* value);
5330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
5340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Returns a random seed in range [1, kMaxRandomSeed] based on the
5350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// given --gtest_random_seed flag value.
5360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orginline int GetRandomSeedFromFlag(Int32 random_seed_flag) {
5370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const unsigned int raw_seed = (random_seed_flag == 0) ?
5380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      static_cast<unsigned int>(GetTimeInMillis()) :
5390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      static_cast<unsigned int>(random_seed_flag);
5400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
5410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Normalizes the actual seed to range [1, kMaxRandomSeed] such that
5420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // it's easy to type.
5430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const int normalized_seed =
5440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      static_cast<int>((raw_seed - 1U) %
5450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                       static_cast<unsigned int>(kMaxRandomSeed)) + 1;
5460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return normalized_seed;
5470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
5480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
5490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Returns the first valid random seed after 'seed'.  The behavior is
5500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// undefined if 'seed' is invalid.  The seed after kMaxRandomSeed is
5510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// considered to be 1.
5520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orginline int GetNextRandomSeed(int seed) {
5530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  GTEST_CHECK_(1 <= seed && seed <= kMaxRandomSeed)
5540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      << "Invalid random seed " << seed << " - must be in [1, "
5550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      << kMaxRandomSeed << "].";
5560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const int next_seed = seed + 1;
5570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return (next_seed > kMaxRandomSeed) ? 1 : next_seed;
5580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
5590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
5600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// This class saves the values of all Google Test flags in its c'tor, and
5610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// restores them in its d'tor.
5620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgclass GTestFlagSaver {
5630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org public:
5640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // The c'tor.
5650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  GTestFlagSaver() {
5660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    also_run_disabled_tests_ = GTEST_FLAG(also_run_disabled_tests);
5670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    break_on_failure_ = GTEST_FLAG(break_on_failure);
5680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    catch_exceptions_ = GTEST_FLAG(catch_exceptions);
5690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    color_ = GTEST_FLAG(color);
5700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    death_test_style_ = GTEST_FLAG(death_test_style);
5710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    death_test_use_fork_ = GTEST_FLAG(death_test_use_fork);
5720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    filter_ = GTEST_FLAG(filter);
5730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    internal_run_death_test_ = GTEST_FLAG(internal_run_death_test);
5740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    list_tests_ = GTEST_FLAG(list_tests);
5750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    output_ = GTEST_FLAG(output);
5760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    print_time_ = GTEST_FLAG(print_time);
5770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    random_seed_ = GTEST_FLAG(random_seed);
5780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    repeat_ = GTEST_FLAG(repeat);
5790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    shuffle_ = GTEST_FLAG(shuffle);
5800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    stack_trace_depth_ = GTEST_FLAG(stack_trace_depth);
5810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    stream_result_to_ = GTEST_FLAG(stream_result_to);
5820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    throw_on_failure_ = GTEST_FLAG(throw_on_failure);
5830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
5840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
5850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // The d'tor is not virtual.  DO NOT INHERIT FROM THIS CLASS.
5860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  ~GTestFlagSaver() {
5870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    GTEST_FLAG(also_run_disabled_tests) = also_run_disabled_tests_;
5880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    GTEST_FLAG(break_on_failure) = break_on_failure_;
5890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    GTEST_FLAG(catch_exceptions) = catch_exceptions_;
5900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    GTEST_FLAG(color) = color_;
5910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    GTEST_FLAG(death_test_style) = death_test_style_;
5920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    GTEST_FLAG(death_test_use_fork) = death_test_use_fork_;
5930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    GTEST_FLAG(filter) = filter_;
5940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    GTEST_FLAG(internal_run_death_test) = internal_run_death_test_;
5950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    GTEST_FLAG(list_tests) = list_tests_;
5960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    GTEST_FLAG(output) = output_;
5970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    GTEST_FLAG(print_time) = print_time_;
5980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    GTEST_FLAG(random_seed) = random_seed_;
5990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    GTEST_FLAG(repeat) = repeat_;
6000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    GTEST_FLAG(shuffle) = shuffle_;
6010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    GTEST_FLAG(stack_trace_depth) = stack_trace_depth_;
6020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    GTEST_FLAG(stream_result_to) = stream_result_to_;
6030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    GTEST_FLAG(throw_on_failure) = throw_on_failure_;
6040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
6050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
6060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org private:
6070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Fields for saving the original values of flags.
6080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  bool also_run_disabled_tests_;
6090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  bool break_on_failure_;
6100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  bool catch_exceptions_;
6110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  std::string color_;
6120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  std::string death_test_style_;
6130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  bool death_test_use_fork_;
6140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  std::string filter_;
6150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  std::string internal_run_death_test_;
6160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  bool list_tests_;
6170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  std::string output_;
6180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  bool print_time_;
6190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  internal::Int32 random_seed_;
6200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  internal::Int32 repeat_;
6210d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  bool shuffle_;
6220d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  internal::Int32 stack_trace_depth_;
6230d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  std::string stream_result_to_;
6240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  bool throw_on_failure_;
6250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org} GTEST_ATTRIBUTE_UNUSED_;
6260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
6270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Converts a Unicode code point to a narrow string in UTF-8 encoding.
6280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// code_point parameter is of type UInt32 because wchar_t may not be
6290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// wide enough to contain a code point.
6300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// If the code_point is not a valid Unicode code point
6310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// (i.e. outside of Unicode range U+0 to U+10FFFF) it will be converted
6320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// to "(Invalid Unicode 0xXXXXXXXX)".
6330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgGTEST_API_ std::string CodePointToUtf8(UInt32 code_point);
6340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
6350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Converts a wide string to a narrow string in UTF-8 encoding.
6360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// The wide string is assumed to have the following encoding:
6370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//   UTF-16 if sizeof(wchar_t) == 2 (on Windows, Cygwin, Symbian OS)
6380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//   UTF-32 if sizeof(wchar_t) == 4 (on Linux)
6390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Parameter str points to a null-terminated wide string.
6400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Parameter num_chars may additionally limit the number
6410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// of wchar_t characters processed. -1 is used when the entire string
6420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// should be processed.
6430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// If the string contains code points that are not valid Unicode code points
6440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// (i.e. outside of Unicode range U+0 to U+10FFFF) they will be output
6450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// as '(Invalid Unicode 0xXXXXXXXX)'. If the string is in UTF16 encoding
6460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// and contains invalid UTF-16 surrogate pairs, values in those pairs
6470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// will be encoded as individual Unicode characters from Basic Normal Plane.
6480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgGTEST_API_ std::string WideStringToUtf8(const wchar_t* str, int num_chars);
6490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
6500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Reads the GTEST_SHARD_STATUS_FILE environment variable, and creates the file
6510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// if the variable is present. If a file already exists at this location, this
6520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// function will write over it. If the variable is present, but the file cannot
6530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// be created, prints an error and exits.
6540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid WriteToShardStatusFileIfNeeded();
6550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
6560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Checks whether sharding is enabled by examining the relevant
6570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// environment variable values. If the variables are present,
6580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// but inconsistent (e.g., shard_index >= total_shards), prints
6590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// an error and exits. If in_subprocess_for_death_test, sharding is
6600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// disabled because it must only be applied to the original test
6610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// process. Otherwise, we could filter out death tests we intended to execute.
6620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgGTEST_API_ bool ShouldShard(const char* total_shards_str,
6630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                            const char* shard_index_str,
6640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                            bool in_subprocess_for_death_test);
6650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
6660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Parses the environment variable var as an Int32. If it is unset,
6670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// returns default_val. If it is not an Int32, prints an error and
6680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// and aborts.
6690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgGTEST_API_ Int32 Int32FromEnvOrDie(const char* env_var, Int32 default_val);
6700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
6710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Given the total number of shards, the shard index, and the test id,
6720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// returns true iff the test should be run on this shard. The test id is
6730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// some arbitrary but unique non-negative integer assigned to each test
6740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// method. Assumes that 0 <= shard_index < total_shards.
6750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgGTEST_API_ bool ShouldRunTestOnShard(
6760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    int total_shards, int shard_index, int test_id);
6770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
6780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// STL container utilities.
6790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
6800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Returns the number of elements in the given container that satisfy
6810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// the given predicate.
6820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgtemplate <class Container, typename Predicate>
6830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orginline int CountIf(const Container& c, Predicate predicate) {
6840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Implemented as an explicit loop since std::count_if() in libCstd on
6850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Solaris has a non-standard signature.
6860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  int count = 0;
6870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  for (typename Container::const_iterator it = c.begin(); it != c.end(); ++it) {
6880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    if (predicate(*it))
6890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      ++count;
6900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
6910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return count;
6920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
6930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
6940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Applies a function/functor to each element in the container.
6950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgtemplate <class Container, typename Functor>
6960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid ForEach(const Container& c, Functor functor) {
6970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  std::for_each(c.begin(), c.end(), functor);
6980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
6990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
7000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Returns the i-th element of the vector, or default_value if i is not
7010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// in range [0, v.size()).
7020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgtemplate <typename E>
7030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orginline E GetElementOr(const std::vector<E>& v, int i, E default_value) {
7040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return (i < 0 || i >= static_cast<int>(v.size())) ? default_value : v[i];
7050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
7060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
7070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Performs an in-place shuffle of a range of the vector's elements.
7080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// 'begin' and 'end' are element indices as an STL-style range;
7090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// i.e. [begin, end) are shuffled, where 'end' == size() means to
7100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// shuffle to the end of the vector.
7110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgtemplate <typename E>
7120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid ShuffleRange(internal::Random* random, int begin, int end,
7130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                  std::vector<E>* v) {
7140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const int size = static_cast<int>(v->size());
7150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  GTEST_CHECK_(0 <= begin && begin <= size)
7160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      << "Invalid shuffle range start " << begin << ": must be in range [0, "
7170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      << size << "].";
7180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  GTEST_CHECK_(begin <= end && end <= size)
7190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      << "Invalid shuffle range finish " << end << ": must be in range ["
7200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      << begin << ", " << size << "].";
7210d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
7220d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Fisher-Yates shuffle, from
7230d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // http://en.wikipedia.org/wiki/Fisher-Yates_shuffle
7240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  for (int range_width = end - begin; range_width >= 2; range_width--) {
7250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const int last_in_range = begin + range_width - 1;
7260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const int selected = begin + random->Generate(range_width);
7270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    std::swap((*v)[selected], (*v)[last_in_range]);
7280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
7290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
7300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
7310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Performs an in-place shuffle of the vector's elements.
7320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgtemplate <typename E>
7330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orginline void Shuffle(internal::Random* random, std::vector<E>* v) {
7340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  ShuffleRange(random, 0, static_cast<int>(v->size()), v);
7350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
7360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
7370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// A function for deleting an object.  Handy for being used as a
7380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// functor.
7390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgtemplate <typename T>
7400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstatic void Delete(T* x) {
7410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  delete x;
7420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
7430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
7440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// A predicate that checks the key of a TestProperty against a known key.
7450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
7460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// TestPropertyKeyIs is copyable.
7470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgclass TestPropertyKeyIs {
7480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org public:
7490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Constructor.
7500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  //
7510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // TestPropertyKeyIs has NO default constructor.
7520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  explicit TestPropertyKeyIs(const std::string& key) : key_(key) {}
7530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
7540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Returns true iff the test name of test property matches on key_.
7550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  bool operator()(const TestProperty& test_property) const {
7560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return test_property.key() == key_;
7570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
7580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
7590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org private:
7600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  std::string key_;
7610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org};
7620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
7630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Class UnitTestOptions.
7640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
7650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// This class contains functions for processing options the user
7660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// specifies when running the tests.  It has only static members.
7670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
7680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// In most cases, the user can specify an option using either an
7690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// environment variable or a command line flag.  E.g. you can set the
7700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// test filter using either GTEST_FILTER or --gtest_filter.  If both
7710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// the variable and the flag are present, the latter overrides the
7720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// former.
7730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgclass GTEST_API_ UnitTestOptions {
7740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org public:
7750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Functions for processing the gtest_output flag.
7760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
7770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Returns the output format, or "" for normal printed output.
7780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  static std::string GetOutputFormat();
7790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
7800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Returns the absolute path of the requested output file, or the
7810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // default (test_detail.xml in the original working directory) if
7820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // none was explicitly specified.
7830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  static std::string GetAbsolutePathToOutputFile();
7840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
7850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Functions for processing the gtest_filter flag.
7860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
7870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Returns true iff the wildcard pattern matches the string.  The
7880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // first ':' or '\0' character in pattern marks the end of it.
7890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  //
7900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // This recursive algorithm isn't very efficient, but is clear and
7910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // works well enough for matching test names, which are short.
7920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  static bool PatternMatchesString(const char *pattern, const char *str);
7930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
7940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Returns true iff the user-specified filter matches the test case
7950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // name and the test name.
7960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  static bool FilterMatchesTest(const std::string &test_case_name,
7970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                const std::string &test_name);
7980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
7990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#if GTEST_OS_WINDOWS
8000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Function for supporting the gtest_catch_exception flag.
8010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
8020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Returns EXCEPTION_EXECUTE_HANDLER if Google Test should handle the
8030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // given SEH exception, or EXCEPTION_CONTINUE_SEARCH otherwise.
8040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // This function is useful as an __except condition.
8050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  static int GTestShouldProcessSEH(DWORD exception_code);
8060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#endif  // GTEST_OS_WINDOWS
8070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
8080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Returns true if "name" matches the ':' separated list of glob-style
8090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // filters in "filter".
8100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  static bool MatchesFilter(const std::string& name, const char* filter);
8110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org};
8120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
8130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Returns the current application's name, removing directory path if that
8140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// is present.  Used by UnitTestOptions::GetOutputFile.
8150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgGTEST_API_ FilePath GetCurrentExecutableName();
8160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
8170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// The role interface for getting the OS stack trace as a string.
8180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgclass OsStackTraceGetterInterface {
8190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org public:
8200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  OsStackTraceGetterInterface() {}
8210d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  virtual ~OsStackTraceGetterInterface() {}
8220d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
8230d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Returns the current OS stack trace as an std::string.  Parameters:
8240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  //
8250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  //   max_depth  - the maximum number of stack frames to be included
8260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  //                in the trace.
8270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  //   skip_count - the number of top frames to be skipped; doesn't count
8280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  //                against max_depth.
8290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  virtual string CurrentStackTrace(int max_depth, int skip_count) = 0;
8300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
8310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // UponLeavingGTest() should be called immediately before Google Test calls
8320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // user code. It saves some information about the current stack that
8330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // CurrentStackTrace() will use to find and hide Google Test stack frames.
8340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  virtual void UponLeavingGTest() = 0;
8350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
8360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org private:
8370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  GTEST_DISALLOW_COPY_AND_ASSIGN_(OsStackTraceGetterInterface);
8380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org};
8390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
8400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// A working implementation of the OsStackTraceGetterInterface interface.
8410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgclass OsStackTraceGetter : public OsStackTraceGetterInterface {
8420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org public:
8430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  OsStackTraceGetter() : caller_frame_(NULL) {}
8440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
8450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  virtual string CurrentStackTrace(int max_depth, int skip_count)
8460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      GTEST_LOCK_EXCLUDED_(mutex_);
8470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
8480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  virtual void UponLeavingGTest() GTEST_LOCK_EXCLUDED_(mutex_);
8490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
8500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // This string is inserted in place of stack frames that are part of
8510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Google Test's implementation.
8520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  static const char* const kElidedFramesMarker;
8530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
8540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org private:
8550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  Mutex mutex_;  // protects all internal state
8560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
8570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // We save the stack frame below the frame that calls user code.
8580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // We do this because the address of the frame immediately below
8590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // the user code changes between the call to UponLeavingGTest()
8600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // and any calls to CurrentStackTrace() from within the user code.
8610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  void* caller_frame_;
8620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
8630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  GTEST_DISALLOW_COPY_AND_ASSIGN_(OsStackTraceGetter);
8640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org};
8650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
8660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Information about a Google Test trace point.
8670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstruct TraceInfo {
8680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const char* file;
8690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  int line;
8700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  std::string message;
8710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org};
8720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
8730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// This is the default global test part result reporter used in UnitTestImpl.
8740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// This class should only be used by UnitTestImpl.
8750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgclass DefaultGlobalTestPartResultReporter
8760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  : public TestPartResultReporterInterface {
8770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org public:
8780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  explicit DefaultGlobalTestPartResultReporter(UnitTestImpl* unit_test);
8790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Implements the TestPartResultReporterInterface. Reports the test part
8800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // result in the current test.
8810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  virtual void ReportTestPartResult(const TestPartResult& result);
8820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
8830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org private:
8840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  UnitTestImpl* const unit_test_;
8850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
8860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  GTEST_DISALLOW_COPY_AND_ASSIGN_(DefaultGlobalTestPartResultReporter);
8870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org};
8880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
8890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// This is the default per thread test part result reporter used in
8900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// UnitTestImpl. This class should only be used by UnitTestImpl.
8910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgclass DefaultPerThreadTestPartResultReporter
8920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    : public TestPartResultReporterInterface {
8930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org public:
8940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  explicit DefaultPerThreadTestPartResultReporter(UnitTestImpl* unit_test);
8950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Implements the TestPartResultReporterInterface. The implementation just
8960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // delegates to the current global test part result reporter of *unit_test_.
8970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  virtual void ReportTestPartResult(const TestPartResult& result);
8980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
8990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org private:
9000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  UnitTestImpl* const unit_test_;
9010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
9020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  GTEST_DISALLOW_COPY_AND_ASSIGN_(DefaultPerThreadTestPartResultReporter);
9030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org};
9040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
9050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// The private implementation of the UnitTest class.  We don't protect
9060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// the methods under a mutex, as this class is not accessible by a
9070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// user and the UnitTest class that delegates work to this class does
9080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// proper locking.
9090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgclass GTEST_API_ UnitTestImpl {
9100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org public:
9110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  explicit UnitTestImpl(UnitTest* parent);
9120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  virtual ~UnitTestImpl();
9130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
9140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // There are two different ways to register your own TestPartResultReporter.
9150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // You can register your own repoter to listen either only for test results
9160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // from the current thread or for results from all threads.
9170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // By default, each per-thread test result repoter just passes a new
9180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // TestPartResult to the global test result reporter, which registers the
9190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // test part result for the currently running test.
9200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
9210d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Returns the global test part result reporter.
9220d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  TestPartResultReporterInterface* GetGlobalTestPartResultReporter();
9230d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
9240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Sets the global test part result reporter.
9250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  void SetGlobalTestPartResultReporter(
9260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      TestPartResultReporterInterface* reporter);
9270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
9280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Returns the test part result reporter for the current thread.
9290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  TestPartResultReporterInterface* GetTestPartResultReporterForCurrentThread();
9300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
9310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Sets the test part result reporter for the current thread.
9320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  void SetTestPartResultReporterForCurrentThread(
9330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      TestPartResultReporterInterface* reporter);
9340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
9350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Gets the number of successful test cases.
9360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  int successful_test_case_count() const;
9370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
9380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Gets the number of failed test cases.
9390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  int failed_test_case_count() const;
9400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
9410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Gets the number of all test cases.
9420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  int total_test_case_count() const;
9430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
9440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Gets the number of all test cases that contain at least one test
9450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // that should run.
9460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  int test_case_to_run_count() const;
9470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
9480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Gets the number of successful tests.
9490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  int successful_test_count() const;
9500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
9510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Gets the number of failed tests.
9520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  int failed_test_count() const;
9530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
9540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Gets the number of disabled tests that will be reported in the XML report.
9550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  int reportable_disabled_test_count() const;
9560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
9570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Gets the number of disabled tests.
9580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  int disabled_test_count() const;
9590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
9600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Gets the number of tests to be printed in the XML report.
9610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  int reportable_test_count() const;
9620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
9630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Gets the number of all tests.
9640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  int total_test_count() const;
9650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
9660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Gets the number of tests that should run.
9670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  int test_to_run_count() const;
9680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
9690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Gets the time of the test program start, in ms from the start of the
9700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // UNIX epoch.
9710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  TimeInMillis start_timestamp() const { return start_timestamp_; }
9720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
9730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Gets the elapsed time, in milliseconds.
9740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  TimeInMillis elapsed_time() const { return elapsed_time_; }
9750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
9760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Returns true iff the unit test passed (i.e. all test cases passed).
9770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  bool Passed() const { return !Failed(); }
9780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
9790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Returns true iff the unit test failed (i.e. some test case failed
9800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // or something outside of all tests failed).
9810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  bool Failed() const {
9820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return failed_test_case_count() > 0 || ad_hoc_test_result()->Failed();
9830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
9840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
9850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Gets the i-th test case among all the test cases. i can range from 0 to
9860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // total_test_case_count() - 1. If i is not in that range, returns NULL.
9870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const TestCase* GetTestCase(int i) const {
9880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const int index = GetElementOr(test_case_indices_, i, -1);
9890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return index < 0 ? NULL : test_cases_[i];
9900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
9910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
9920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Gets the i-th test case among all the test cases. i can range from 0 to
9930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // total_test_case_count() - 1. If i is not in that range, returns NULL.
9940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  TestCase* GetMutableTestCase(int i) {
9950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const int index = GetElementOr(test_case_indices_, i, -1);
9960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return index < 0 ? NULL : test_cases_[index];
9970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
9980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
9990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Provides access to the event listener list.
10000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  TestEventListeners* listeners() { return &listeners_; }
10010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
10020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Returns the TestResult for the test that's currently running, or
10030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // the TestResult for the ad hoc test if no test is running.
10040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  TestResult* current_test_result();
10050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
10060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Returns the TestResult for the ad hoc test.
10070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const TestResult* ad_hoc_test_result() const { return &ad_hoc_test_result_; }
10080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
10090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Sets the OS stack trace getter.
10100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  //
10110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Does nothing if the input and the current OS stack trace getter
10120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // are the same; otherwise, deletes the old getter and makes the
10130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // input the current getter.
10140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  void set_os_stack_trace_getter(OsStackTraceGetterInterface* getter);
10150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
10160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Returns the current OS stack trace getter if it is not NULL;
10170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // otherwise, creates an OsStackTraceGetter, makes it the current
10180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // getter, and returns it.
10190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  OsStackTraceGetterInterface* os_stack_trace_getter();
10200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
10210d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Returns the current OS stack trace as an std::string.
10220d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  //
10230d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // The maximum number of stack frames to be included is specified by
10240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // the gtest_stack_trace_depth flag.  The skip_count parameter
10250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // specifies the number of top frames to be skipped, which doesn't
10260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // count against the number of frames to be included.
10270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  //
10280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // For example, if Foo() calls Bar(), which in turn calls
10290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // CurrentOsStackTraceExceptTop(1), Foo() will be included in the
10300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // trace but Bar() and CurrentOsStackTraceExceptTop() won't.
10310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  std::string CurrentOsStackTraceExceptTop(int skip_count) GTEST_NO_INLINE_;
10320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
10330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Finds and returns a TestCase with the given name.  If one doesn't
10340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // exist, creates one and returns it.
10350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  //
10360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Arguments:
10370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  //
10380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  //   test_case_name: name of the test case
10390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  //   type_param:     the name of the test's type parameter, or NULL if
10400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  //                   this is not a typed or a type-parameterized test.
10410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  //   set_up_tc:      pointer to the function that sets up the test case
10420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  //   tear_down_tc:   pointer to the function that tears down the test case
10430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  TestCase* GetTestCase(const char* test_case_name,
10440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                        const char* type_param,
10450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                        Test::SetUpTestCaseFunc set_up_tc,
10460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                        Test::TearDownTestCaseFunc tear_down_tc);
10470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
10480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Adds a TestInfo to the unit test.
10490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  //
10500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Arguments:
10510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  //
10520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  //   set_up_tc:    pointer to the function that sets up the test case
10530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  //   tear_down_tc: pointer to the function that tears down the test case
10540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  //   test_info:    the TestInfo object
10550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  void AddTestInfo(Test::SetUpTestCaseFunc set_up_tc,
10560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                   Test::TearDownTestCaseFunc tear_down_tc,
10570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                   TestInfo* test_info) {
10580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // In order to support thread-safe death tests, we need to
10590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // remember the original working directory when the test program
10600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // was first invoked.  We cannot do this in RUN_ALL_TESTS(), as
10610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // the user may have changed the current directory before calling
10620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // RUN_ALL_TESTS().  Therefore we capture the current directory in
10630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // AddTestInfo(), which is called to register a TEST or TEST_F
10640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // before main() is reached.
10650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    if (original_working_dir_.IsEmpty()) {
10660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      original_working_dir_.Set(FilePath::GetCurrentDir());
10670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      GTEST_CHECK_(!original_working_dir_.IsEmpty())
10680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          << "Failed to get the current working directory.";
10690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    }
10700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
10710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    GetTestCase(test_info->test_case_name(),
10720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                test_info->type_param(),
10730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                set_up_tc,
10740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                tear_down_tc)->AddTestInfo(test_info);
10750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
10760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
10770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#if GTEST_HAS_PARAM_TEST
10780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Returns ParameterizedTestCaseRegistry object used to keep track of
10790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // value-parameterized tests and instantiate and register them.
10800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  internal::ParameterizedTestCaseRegistry& parameterized_test_registry() {
10810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return parameterized_test_registry_;
10820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
10830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#endif  // GTEST_HAS_PARAM_TEST
10840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
10850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Sets the TestCase object for the test that's currently running.
10860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  void set_current_test_case(TestCase* a_current_test_case) {
10870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    current_test_case_ = a_current_test_case;
10880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
10890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
10900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Sets the TestInfo object for the test that's currently running.  If
10910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // current_test_info is NULL, the assertion results will be stored in
10920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // ad_hoc_test_result_.
10930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  void set_current_test_info(TestInfo* a_current_test_info) {
10940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    current_test_info_ = a_current_test_info;
10950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
10960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
10970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Registers all parameterized tests defined using TEST_P and
10980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // INSTANTIATE_TEST_CASE_P, creating regular tests for each test/parameter
10990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // combination. This method can be called more then once; it has guards
11000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // protecting from registering the tests more then once.  If
11010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // value-parameterized tests are disabled, RegisterParameterizedTests is
11020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // present but does nothing.
11030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  void RegisterParameterizedTests();
11040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
11050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Runs all tests in this UnitTest object, prints the result, and
11060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // returns true if all tests are successful.  If any exception is
11070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // thrown during a test, this test is considered to be failed, but
11080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // the rest of the tests will still be run.
11090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  bool RunAllTests();
11100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
11110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Clears the results of all tests, except the ad hoc tests.
11120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  void ClearNonAdHocTestResult() {
11130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    ForEach(test_cases_, TestCase::ClearTestCaseResult);
11140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
11150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
11160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Clears the results of ad-hoc test assertions.
11170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  void ClearAdHocTestResult() {
11180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    ad_hoc_test_result_.Clear();
11190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
11200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
11210d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Adds a TestProperty to the current TestResult object when invoked in a
11220d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // context of a test or a test case, or to the global property set. If the
11230d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // result already contains a property with the same key, the value will be
11240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // updated.
11250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  void RecordProperty(const TestProperty& test_property);
11260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
11270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  enum ReactionToSharding {
11280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    HONOR_SHARDING_PROTOCOL,
11290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    IGNORE_SHARDING_PROTOCOL
11300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  };
11310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
11320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Matches the full name of each test against the user-specified
11330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // filter to decide whether the test should run, then records the
11340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // result in each TestCase and TestInfo object.
11350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // If shard_tests == HONOR_SHARDING_PROTOCOL, further filters tests
11360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // based on sharding variables in the environment.
11370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Returns the number of tests that should run.
11380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  int FilterTests(ReactionToSharding shard_tests);
11390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
11400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Prints the names of the tests matching the user-specified filter flag.
11410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  void ListTestsMatchingFilter();
11420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
11430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const TestCase* current_test_case() const { return current_test_case_; }
11440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  TestInfo* current_test_info() { return current_test_info_; }
11450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const TestInfo* current_test_info() const { return current_test_info_; }
11460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
11470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Returns the vector of environments that need to be set-up/torn-down
11480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // before/after the tests are run.
11490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  std::vector<Environment*>& environments() { return environments_; }
11500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
11510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Getters for the per-thread Google Test trace stack.
11520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  std::vector<TraceInfo>& gtest_trace_stack() {
11530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return *(gtest_trace_stack_.pointer());
11540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
11550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const std::vector<TraceInfo>& gtest_trace_stack() const {
11560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return gtest_trace_stack_.get();
11570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
11580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
11590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#if GTEST_HAS_DEATH_TEST
11600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  void InitDeathTestSubprocessControlInfo() {
11610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    internal_run_death_test_flag_.reset(ParseInternalRunDeathTestFlag());
11620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
11630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Returns a pointer to the parsed --gtest_internal_run_death_test
11640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // flag, or NULL if that flag was not specified.
11650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // This information is useful only in a death test child process.
11660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Must not be called before a call to InitGoogleTest.
11670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const InternalRunDeathTestFlag* internal_run_death_test_flag() const {
11680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return internal_run_death_test_flag_.get();
11690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
11700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
11710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Returns a pointer to the current death test factory.
11720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  internal::DeathTestFactory* death_test_factory() {
11730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return death_test_factory_.get();
11740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
11750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
11760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  void SuppressTestEventsIfInSubprocess();
11770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
11780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  friend class ReplaceDeathTestFactory;
11790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#endif  // GTEST_HAS_DEATH_TEST
11800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
11810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Initializes the event listener performing XML output as specified by
11820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // UnitTestOptions. Must not be called before InitGoogleTest.
11830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  void ConfigureXmlOutput();
11840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
11850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#if GTEST_CAN_STREAM_RESULTS_
11860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Initializes the event listener for streaming test results to a socket.
11870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Must not be called before InitGoogleTest.
11880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  void ConfigureStreamingOutput();
11890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#endif
11900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
11910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Performs initialization dependent upon flag values obtained in
11920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // ParseGoogleTestFlagsOnly.  Is called from InitGoogleTest after the call to
11930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // ParseGoogleTestFlagsOnly.  In case a user neglects to call InitGoogleTest
11940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // this function is also called from RunAllTests.  Since this function can be
11950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // called more than once, it has to be idempotent.
11960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  void PostFlagParsingInit();
11970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
11980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Gets the random seed used at the start of the current test iteration.
11990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  int random_seed() const { return random_seed_; }
12000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
12010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Gets the random number generator.
12020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  internal::Random* random() { return &random_; }
12030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
12040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Shuffles all test cases, and the tests within each test case,
12050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // making sure that death tests are still run first.
12060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  void ShuffleTests();
12070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
12080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Restores the test cases and tests to their order before the first shuffle.
12090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  void UnshuffleTests();
12100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
12110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Returns the value of GTEST_FLAG(catch_exceptions) at the moment
12120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // UnitTest::Run() starts.
12130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  bool catch_exceptions() const { return catch_exceptions_; }
12140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
12150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org private:
12160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  friend class ::testing::UnitTest;
12170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
12180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Used by UnitTest::Run() to capture the state of
12190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // GTEST_FLAG(catch_exceptions) at the moment it starts.
12200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  void set_catch_exceptions(bool value) { catch_exceptions_ = value; }
12210d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
12220d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // The UnitTest object that owns this implementation object.
12230d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  UnitTest* const parent_;
12240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
12250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // The working directory when the first TEST() or TEST_F() was
12260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // executed.
12270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  internal::FilePath original_working_dir_;
12280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
12290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // The default test part result reporters.
12300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  DefaultGlobalTestPartResultReporter default_global_test_part_result_reporter_;
12310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  DefaultPerThreadTestPartResultReporter
12320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      default_per_thread_test_part_result_reporter_;
12330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
12340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Points to (but doesn't own) the global test part result reporter.
12350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  TestPartResultReporterInterface* global_test_part_result_repoter_;
12360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
12370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Protects read and write access to global_test_part_result_reporter_.
12380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  internal::Mutex global_test_part_result_reporter_mutex_;
12390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
12400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Points to (but doesn't own) the per-thread test part result reporter.
12410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  internal::ThreadLocal<TestPartResultReporterInterface*>
12420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      per_thread_test_part_result_reporter_;
12430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
12440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // The vector of environments that need to be set-up/torn-down
12450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // before/after the tests are run.
12460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  std::vector<Environment*> environments_;
12470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
12480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // The vector of TestCases in their original order.  It owns the
12490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // elements in the vector.
12500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  std::vector<TestCase*> test_cases_;
12510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
12520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Provides a level of indirection for the test case list to allow
12530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // easy shuffling and restoring the test case order.  The i-th
12540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // element of this vector is the index of the i-th test case in the
12550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // shuffled order.
12560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  std::vector<int> test_case_indices_;
12570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
12580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#if GTEST_HAS_PARAM_TEST
12590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // ParameterizedTestRegistry object used to register value-parameterized
12600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // tests.
12610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  internal::ParameterizedTestCaseRegistry parameterized_test_registry_;
12620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
12630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Indicates whether RegisterParameterizedTests() has been called already.
12640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  bool parameterized_tests_registered_;
12650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#endif  // GTEST_HAS_PARAM_TEST
12660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
12670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Index of the last death test case registered.  Initially -1.
12680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  int last_death_test_case_;
12690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
12700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // This points to the TestCase for the currently running test.  It
12710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // changes as Google Test goes through one test case after another.
12720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // When no test is running, this is set to NULL and Google Test
12730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // stores assertion results in ad_hoc_test_result_.  Initially NULL.
12740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  TestCase* current_test_case_;
12750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
12760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // This points to the TestInfo for the currently running test.  It
12770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // changes as Google Test goes through one test after another.  When
12780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // no test is running, this is set to NULL and Google Test stores
12790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // assertion results in ad_hoc_test_result_.  Initially NULL.
12800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  TestInfo* current_test_info_;
12810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
12820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Normally, a user only writes assertions inside a TEST or TEST_F,
12830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // or inside a function called by a TEST or TEST_F.  Since Google
12840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Test keeps track of which test is current running, it can
12850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // associate such an assertion with the test it belongs to.
12860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  //
12870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // If an assertion is encountered when no TEST or TEST_F is running,
12880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Google Test attributes the assertion result to an imaginary "ad hoc"
12890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // test, and records the result in ad_hoc_test_result_.
12900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  TestResult ad_hoc_test_result_;
12910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
12920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // The list of event listeners that can be used to track events inside
12930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Google Test.
12940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  TestEventListeners listeners_;
12950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
12960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // The OS stack trace getter.  Will be deleted when the UnitTest
12970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // object is destructed.  By default, an OsStackTraceGetter is used,
12980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // but the user can set this field to use a custom getter if that is
12990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // desired.
13000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  OsStackTraceGetterInterface* os_stack_trace_getter_;
13010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
13020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // True iff PostFlagParsingInit() has been called.
13030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  bool post_flag_parse_init_performed_;
13040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
13050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // The random number seed used at the beginning of the test run.
13060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  int random_seed_;
13070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
13080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Our random number generator.
13090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  internal::Random random_;
13100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
13110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // The time of the test program start, in ms from the start of the
13120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // UNIX epoch.
13130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  TimeInMillis start_timestamp_;
13140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
13150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // How long the test took to run, in milliseconds.
13160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  TimeInMillis elapsed_time_;
13170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
13180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#if GTEST_HAS_DEATH_TEST
13190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // The decomposed components of the gtest_internal_run_death_test flag,
13200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // parsed when RUN_ALL_TESTS is called.
13210d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  internal::scoped_ptr<InternalRunDeathTestFlag> internal_run_death_test_flag_;
13220d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  internal::scoped_ptr<internal::DeathTestFactory> death_test_factory_;
13230d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#endif  // GTEST_HAS_DEATH_TEST
13240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
13250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // A per-thread stack of traces created by the SCOPED_TRACE() macro.
13260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  internal::ThreadLocal<std::vector<TraceInfo> > gtest_trace_stack_;
13270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
13280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // The value of GTEST_FLAG(catch_exceptions) at the moment RunAllTests()
13290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // starts.
13300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  bool catch_exceptions_;
13310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
13320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  GTEST_DISALLOW_COPY_AND_ASSIGN_(UnitTestImpl);
13330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org};  // class UnitTestImpl
13340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
13350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Convenience function for accessing the global UnitTest
13360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// implementation object.
13370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orginline UnitTestImpl* GetUnitTestImpl() {
13380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return UnitTest::GetInstance()->impl();
13390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
13400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
13410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#if GTEST_USES_SIMPLE_RE
13420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
13430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Internal helper functions for implementing the simple regular
13440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// expression matcher.
13450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgGTEST_API_ bool IsInSet(char ch, const char* str);
13460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgGTEST_API_ bool IsAsciiDigit(char ch);
13470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgGTEST_API_ bool IsAsciiPunct(char ch);
13480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgGTEST_API_ bool IsRepeat(char ch);
13490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgGTEST_API_ bool IsAsciiWhiteSpace(char ch);
13500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgGTEST_API_ bool IsAsciiWordChar(char ch);
13510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgGTEST_API_ bool IsValidEscape(char ch);
13520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgGTEST_API_ bool AtomMatchesChar(bool escaped, char pattern, char ch);
13530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgGTEST_API_ bool ValidateRegex(const char* regex);
13540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgGTEST_API_ bool MatchRegexAtHead(const char* regex, const char* str);
13550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgGTEST_API_ bool MatchRepetitionAndRegexAtHead(
13560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    bool escaped, char ch, char repeat, const char* regex, const char* str);
13570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgGTEST_API_ bool MatchRegexAnywhere(const char* regex, const char* str);
13580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
13590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#endif  // GTEST_USES_SIMPLE_RE
13600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
13610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Parses the command line for Google Test flags, without initializing
13620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// other parts of Google Test.
13630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgGTEST_API_ void ParseGoogleTestFlagsOnly(int* argc, char** argv);
13640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgGTEST_API_ void ParseGoogleTestFlagsOnly(int* argc, wchar_t** argv);
13650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
13660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#if GTEST_HAS_DEATH_TEST
13670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
13680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Returns the message describing the last system error, regardless of the
13690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// platform.
13700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgGTEST_API_ std::string GetLastErrnoDescription();
13710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
13720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# if GTEST_OS_WINDOWS
13730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Provides leak-safe Windows kernel handle ownership.
13740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgclass AutoHandle {
13750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org public:
13760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  AutoHandle() : handle_(INVALID_HANDLE_VALUE) {}
13770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  explicit AutoHandle(HANDLE handle) : handle_(handle) {}
13780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
13790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  ~AutoHandle() { Reset(); }
13800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
13810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  HANDLE Get() const { return handle_; }
13820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  void Reset() { Reset(INVALID_HANDLE_VALUE); }
13830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  void Reset(HANDLE handle) {
13840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    if (handle != handle_) {
13850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      if (handle_ != INVALID_HANDLE_VALUE)
13860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        ::CloseHandle(handle_);
13870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      handle_ = handle;
13880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    }
13890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
13900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
13910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org private:
13920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  HANDLE handle_;
13930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
13940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  GTEST_DISALLOW_COPY_AND_ASSIGN_(AutoHandle);
13950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org};
13960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# endif  // GTEST_OS_WINDOWS
13970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
13980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Attempts to parse a string into a positive integer pointed to by the
13990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// number parameter.  Returns true if that is possible.
14000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we can use
14010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// it here.
14020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgtemplate <typename Integer>
14030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgbool ParseNaturalNumber(const ::std::string& str, Integer* number) {
14040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Fail fast if the given string does not begin with a digit;
14050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // this bypasses strtoXXX's "optional leading whitespace and plus
14060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // or minus sign" semantics, which are undesirable here.
14070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (str.empty() || !IsDigit(str[0])) {
14080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return false;
14090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
14100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  errno = 0;
14110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
14120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  char* end;
14130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // BiggestConvertible is the largest integer type that system-provided
14140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // string-to-number conversion routines can return.
14150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
14160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# if GTEST_OS_WINDOWS && !defined(__GNUC__)
14170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
14180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // MSVC and C++ Builder define __int64 instead of the standard long long.
14190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  typedef unsigned __int64 BiggestConvertible;
14200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const BiggestConvertible parsed = _strtoui64(str.c_str(), &end, 10);
14210d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
14220d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# else
14230d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
14240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  typedef unsigned long long BiggestConvertible;  // NOLINT
14250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const BiggestConvertible parsed = strtoull(str.c_str(), &end, 10);
14260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
14270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# endif  // GTEST_OS_WINDOWS && !defined(__GNUC__)
14280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
14290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const bool parse_success = *end == '\0' && errno == 0;
14300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
14310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // TODO(vladl@google.com): Convert this to compile time assertion when it is
14320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // available.
14330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  GTEST_CHECK_(sizeof(Integer) <= sizeof(parsed));
14340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
14350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const Integer result = static_cast<Integer>(parsed);
14360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (parse_success && static_cast<BiggestConvertible>(result) == parsed) {
14370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    *number = result;
14380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return true;
14390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
14400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return false;
14410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
14420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#endif  // GTEST_HAS_DEATH_TEST
14430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
14440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// TestResult contains some private methods that should be hidden from
14450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Google Test user but are required for testing. This class allow our tests
14460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// to access them.
14470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
14480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// This class is supplied only for the purpose of testing Google Test's own
14490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// constructs. Do not use it in user tests, either directly or indirectly.
14500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgclass TestResultAccessor {
14510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org public:
14520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  static void RecordProperty(TestResult* test_result,
14530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                             const std::string& xml_element,
14540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                             const TestProperty& property) {
14550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    test_result->RecordProperty(xml_element, property);
14560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
14570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
14580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  static void ClearTestPartResults(TestResult* test_result) {
14590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    test_result->ClearTestPartResults();
14600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
14610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
14620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  static const std::vector<testing::TestPartResult>& test_part_results(
14630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      const TestResult& test_result) {
14640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return test_result.test_part_results();
14650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
14660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org};
14670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
14680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#if GTEST_CAN_STREAM_RESULTS_
14690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
14700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Streams test results to the given port on the given host machine.
14710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgclass StreamingListener : public EmptyTestEventListener {
14720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org public:
14730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Abstract base class for writing strings to a socket.
14740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  class AbstractSocketWriter {
14750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org   public:
14760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    virtual ~AbstractSocketWriter() {}
14770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
14780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // Sends a string to the socket.
14790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    virtual void Send(const string& message) = 0;
14800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
14810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // Closes the socket.
14820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    virtual void CloseConnection() {}
14830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
14840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // Sends a string and a newline to the socket.
14850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    void SendLn(const string& message) {
14860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      Send(message + "\n");
14870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    }
14880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  };
14890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
14900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Concrete class for actually writing strings to a socket.
14910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  class SocketWriter : public AbstractSocketWriter {
14920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org   public:
14930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    SocketWriter(const string& host, const string& port)
14940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        : sockfd_(-1), host_name_(host), port_num_(port) {
14950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      MakeConnection();
14960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    }
14970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
14980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    virtual ~SocketWriter() {
14990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      if (sockfd_ != -1)
15000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        CloseConnection();
15010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    }
15020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
15030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // Sends a string to the socket.
15040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    virtual void Send(const string& message) {
15050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      GTEST_CHECK_(sockfd_ != -1)
15060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          << "Send() can be called only when there is a connection.";
15070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
15080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      const int len = static_cast<int>(message.length());
15090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      if (write(sockfd_, message.c_str(), len) != len) {
15100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        GTEST_LOG_(WARNING)
15110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org            << "stream_result_to: failed to stream to "
15120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org            << host_name_ << ":" << port_num_;
15130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      }
15140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    }
15150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
15160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org   private:
15170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // Creates a client socket and connects to the server.
15180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    void MakeConnection();
15190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
15200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // Closes the socket.
15210d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    void CloseConnection() {
15220d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      GTEST_CHECK_(sockfd_ != -1)
15230d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          << "CloseConnection() can be called only when there is a connection.";
15240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
15250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      close(sockfd_);
15260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      sockfd_ = -1;
15270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    }
15280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
15290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    int sockfd_;  // socket file descriptor
15300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const string host_name_;
15310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const string port_num_;
15320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
15330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    GTEST_DISALLOW_COPY_AND_ASSIGN_(SocketWriter);
15340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  };  // class SocketWriter
15350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
15360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Escapes '=', '&', '%', and '\n' characters in str as "%xx".
15370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  static string UrlEncode(const char* str);
15380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
15390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  StreamingListener(const string& host, const string& port)
15400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      : socket_writer_(new SocketWriter(host, port)) { Start(); }
15410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
15420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  explicit StreamingListener(AbstractSocketWriter* socket_writer)
15430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      : socket_writer_(socket_writer) { Start(); }
15440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
15450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  void OnTestProgramStart(const UnitTest& /* unit_test */) {
15460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    SendLn("event=TestProgramStart");
15470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
15480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
15490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  void OnTestProgramEnd(const UnitTest& unit_test) {
15500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // Note that Google Test current only report elapsed time for each
15510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // test iteration, not for the entire test program.
15520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    SendLn("event=TestProgramEnd&passed=" + FormatBool(unit_test.Passed()));
15530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
15540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // Notify the streaming server to stop.
15550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    socket_writer_->CloseConnection();
15560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
15570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
15580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  void OnTestIterationStart(const UnitTest& /* unit_test */, int iteration) {
15590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    SendLn("event=TestIterationStart&iteration=" +
15600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org           StreamableToString(iteration));
15610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
15620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
15630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  void OnTestIterationEnd(const UnitTest& unit_test, int /* iteration */) {
15640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    SendLn("event=TestIterationEnd&passed=" +
15650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org           FormatBool(unit_test.Passed()) + "&elapsed_time=" +
15660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org           StreamableToString(unit_test.elapsed_time()) + "ms");
15670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
15680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
15690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  void OnTestCaseStart(const TestCase& test_case) {
15700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    SendLn(std::string("event=TestCaseStart&name=") + test_case.name());
15710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
15720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
15730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  void OnTestCaseEnd(const TestCase& test_case) {
15740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    SendLn("event=TestCaseEnd&passed=" + FormatBool(test_case.Passed())
15750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org           + "&elapsed_time=" + StreamableToString(test_case.elapsed_time())
15760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org           + "ms");
15770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
15780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
15790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  void OnTestStart(const TestInfo& test_info) {
15800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    SendLn(std::string("event=TestStart&name=") + test_info.name());
15810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
15820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
15830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  void OnTestEnd(const TestInfo& test_info) {
15840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    SendLn("event=TestEnd&passed=" +
15850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org           FormatBool((test_info.result())->Passed()) +
15860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org           "&elapsed_time=" +
15870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org           StreamableToString((test_info.result())->elapsed_time()) + "ms");
15880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
15890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
15900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  void OnTestPartResult(const TestPartResult& test_part_result) {
15910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const char* file_name = test_part_result.file_name();
15920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    if (file_name == NULL)
15930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      file_name = "";
15940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    SendLn("event=TestPartResult&file=" + UrlEncode(file_name) +
15950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org           "&line=" + StreamableToString(test_part_result.line_number()) +
15960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org           "&message=" + UrlEncode(test_part_result.message()));
15970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
15980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
15990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org private:
16000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Sends the given message and a newline to the socket.
16010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  void SendLn(const string& message) { socket_writer_->SendLn(message); }
16020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
16030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Called at the start of streaming to notify the receiver what
16040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // protocol we are using.
16050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  void Start() { SendLn("gtest_streaming_protocol_version=1.0"); }
16060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
16070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  string FormatBool(bool value) { return value ? "1" : "0"; }
16080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
16090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const scoped_ptr<AbstractSocketWriter> socket_writer_;
16100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
16110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  GTEST_DISALLOW_COPY_AND_ASSIGN_(StreamingListener);
16120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org};  // class StreamingListener
16130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
16140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#endif  // GTEST_CAN_STREAM_RESULTS_
16150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
16160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}  // namespace internal
16170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}  // namespace testing
16180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
16190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#endif  // GTEST_SRC_GTEST_INTERNAL_INL_H_
16200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#undef GTEST_IMPLEMENTATION_
16210d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
16220d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#if GTEST_OS_WINDOWS
16230d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# define vsnprintf _vsnprintf
16240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#endif  // GTEST_OS_WINDOWS
16250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
16260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgnamespace testing {
16270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
16280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgusing internal::CountIf;
16290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgusing internal::ForEach;
16300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgusing internal::GetElementOr;
16310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgusing internal::Shuffle;
16320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
16330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Constants.
16340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
16350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// A test whose test case name or test name matches this filter is
16360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// disabled and not run.
16370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstatic const char kDisableTestFilter[] = "DISABLED_*:*/DISABLED_*";
16380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
16390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// A test case whose name matches this filter is considered a death
16400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// test case and will be run before test cases whose name doesn't
16410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// match this filter.
16420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstatic const char kDeathTestCaseFilter[] = "*DeathTest:*DeathTest/*";
16430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
16440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// A test filter that matches everything.
16450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstatic const char kUniversalFilter[] = "*";
16460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
16470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// The default output file for XML output.
16480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstatic const char kDefaultOutputFile[] = "test_detail.xml";
16490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
16500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// The environment variable name for the test shard index.
16510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstatic const char kTestShardIndex[] = "GTEST_SHARD_INDEX";
16520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// The environment variable name for the total number of test shards.
16530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstatic const char kTestTotalShards[] = "GTEST_TOTAL_SHARDS";
16540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// The environment variable name for the test shard status file.
16550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstatic const char kTestShardStatusFile[] = "GTEST_SHARD_STATUS_FILE";
16560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
16570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgnamespace internal {
16580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
16590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// The text used in failure messages to indicate the start of the
16600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// stack trace.
16610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgconst char kStackTraceMarker[] = "\nStack trace:\n";
16620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
16630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// g_help_flag is true iff the --help flag or an equivalent form is
16640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// specified on the command line.
16650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgbool g_help_flag = false;
16660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
16670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}  // namespace internal
16680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
16690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstatic const char* GetDefaultFilter() {
16700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return kUniversalFilter;
16710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
16720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
16730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgGTEST_DEFINE_bool_(
16740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    also_run_disabled_tests,
16750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    internal::BoolFromGTestEnv("also_run_disabled_tests", false),
16760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    "Run disabled tests too, in addition to the tests normally being run.");
16770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
16780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgGTEST_DEFINE_bool_(
16790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    break_on_failure,
16800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    internal::BoolFromGTestEnv("break_on_failure", false),
16810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    "True iff a failed assertion should be a debugger break-point.");
16820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
16830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgGTEST_DEFINE_bool_(
16840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    catch_exceptions,
16850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    internal::BoolFromGTestEnv("catch_exceptions", true),
16860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    "True iff " GTEST_NAME_
16870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    " should catch exceptions and treat them as test failures.");
16880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
16890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgGTEST_DEFINE_string_(
16900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    color,
16910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    internal::StringFromGTestEnv("color", "auto"),
16920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    "Whether to use colors in the output.  Valid values: yes, no, "
16930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    "and auto.  'auto' means to use colors if the output is "
16940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    "being sent to a terminal and the TERM environment variable "
16950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    "is set to a terminal type that supports colors.");
16960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
16970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgGTEST_DEFINE_string_(
16980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    filter,
16990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    internal::StringFromGTestEnv("filter", GetDefaultFilter()),
17000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    "A colon-separated list of glob (not regex) patterns "
17010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    "for filtering the tests to run, optionally followed by a "
17020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    "'-' and a : separated list of negative patterns (tests to "
17030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    "exclude).  A test is run if it matches one of the positive "
17040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    "patterns and does not match any of the negative patterns.");
17050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
17060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgGTEST_DEFINE_bool_(list_tests, false,
17070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                   "List all tests without running them.");
17080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
17090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgGTEST_DEFINE_string_(
17100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    output,
17110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    internal::StringFromGTestEnv("output", ""),
17120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    "A format (currently must be \"xml\"), optionally followed "
17130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    "by a colon and an output file name or directory. A directory "
17140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    "is indicated by a trailing pathname separator. "
17150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    "Examples: \"xml:filename.xml\", \"xml::directoryname/\". "
17160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    "If a directory is specified, output files will be created "
17170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    "within that directory, with file-names based on the test "
17180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    "executable's name and, if necessary, made unique by adding "
17190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    "digits.");
17200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
17210d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgGTEST_DEFINE_bool_(
17220d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    print_time,
17230d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    internal::BoolFromGTestEnv("print_time", true),
17240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    "True iff " GTEST_NAME_
17250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    " should display elapsed time in text output.");
17260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
17270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgGTEST_DEFINE_int32_(
17280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    random_seed,
17290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    internal::Int32FromGTestEnv("random_seed", 0),
17300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    "Random number seed to use when shuffling test orders.  Must be in range "
17310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    "[1, 99999], or 0 to use a seed based on the current time.");
17320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
17330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgGTEST_DEFINE_int32_(
17340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    repeat,
17350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    internal::Int32FromGTestEnv("repeat", 1),
17360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    "How many times to repeat each test.  Specify a negative number "
17370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    "for repeating forever.  Useful for shaking out flaky tests.");
17380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
17390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgGTEST_DEFINE_bool_(
17400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    show_internal_stack_frames, false,
17410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    "True iff " GTEST_NAME_ " should include internal stack frames when "
17420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    "printing test failure stack traces.");
17430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
17440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgGTEST_DEFINE_bool_(
17450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    shuffle,
17460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    internal::BoolFromGTestEnv("shuffle", false),
17470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    "True iff " GTEST_NAME_
17480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    " should randomize tests' order on every run.");
17490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
17500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgGTEST_DEFINE_int32_(
17510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    stack_trace_depth,
17520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    internal::Int32FromGTestEnv("stack_trace_depth", kMaxStackTraceDepth),
17530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    "The maximum number of stack frames to print when an "
17540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    "assertion fails.  The valid range is 0 through 100, inclusive.");
17550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
17560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgGTEST_DEFINE_string_(
17570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    stream_result_to,
17580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    internal::StringFromGTestEnv("stream_result_to", ""),
17590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    "This flag specifies the host name and the port number on which to stream "
17600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    "test results. Example: \"localhost:555\". The flag is effective only on "
17610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    "Linux.");
17620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
17630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgGTEST_DEFINE_bool_(
17640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    throw_on_failure,
17650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    internal::BoolFromGTestEnv("throw_on_failure", false),
17660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    "When this flag is specified, a failed assertion will throw an exception "
17670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    "if exceptions are enabled or exit the program with a non-zero code "
17680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    "otherwise.");
17690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
17700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgnamespace internal {
17710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
17720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Generates a random number from [0, range), using a Linear
17730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Congruential Generator (LCG).  Crashes if 'range' is 0 or greater
17740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// than kMaxRange.
17750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgUInt32 Random::Generate(UInt32 range) {
17760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // These constants are the same as are used in glibc's rand(3).
17770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  state_ = (1103515245U*state_ + 12345U) % kMaxRange;
17780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
17790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  GTEST_CHECK_(range > 0)
17800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      << "Cannot generate a number in the range [0, 0).";
17810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  GTEST_CHECK_(range <= kMaxRange)
17820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      << "Generation of a number in [0, " << range << ") was requested, "
17830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      << "but this can only generate numbers in [0, " << kMaxRange << ").";
17840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
17850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Converting via modulus introduces a bit of downward bias, but
17860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // it's simple, and a linear congruential generator isn't too good
17870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // to begin with.
17880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return state_ % range;
17890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
17900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
17910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// GTestIsInitialized() returns true iff the user has initialized
17920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Google Test.  Useful for catching the user mistake of not initializing
17930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Google Test before calling RUN_ALL_TESTS().
17940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
17950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// A user must call testing::InitGoogleTest() to initialize Google
17960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Test.  g_init_gtest_count is set to the number of times
17970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// InitGoogleTest() has been called.  We don't protect this variable
17980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// under a mutex as it is only accessed in the main thread.
17990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgGTEST_API_ int g_init_gtest_count = 0;
18000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstatic bool GTestIsInitialized() { return g_init_gtest_count != 0; }
18010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
18020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Iterates over a vector of TestCases, keeping a running sum of the
18030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// results of calling a given int-returning method on each.
18040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Returns the sum.
18050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstatic int SumOverTestCaseList(const std::vector<TestCase*>& case_list,
18060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                               int (TestCase::*method)() const) {
18070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  int sum = 0;
18080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  for (size_t i = 0; i < case_list.size(); i++) {
18090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    sum += (case_list[i]->*method)();
18100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
18110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return sum;
18120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
18130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
18140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Returns true iff the test case passed.
18150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstatic bool TestCasePassed(const TestCase* test_case) {
18160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return test_case->should_run() && test_case->Passed();
18170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
18180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
18190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Returns true iff the test case failed.
18200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstatic bool TestCaseFailed(const TestCase* test_case) {
18210d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return test_case->should_run() && test_case->Failed();
18220d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
18230d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
18240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Returns true iff test_case contains at least one test that should
18250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// run.
18260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstatic bool ShouldRunTestCase(const TestCase* test_case) {
18270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return test_case->should_run();
18280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
18290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
18300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// AssertHelper constructor.
18310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgAssertHelper::AssertHelper(TestPartResult::Type type,
18320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                           const char* file,
18330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                           int line,
18340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                           const char* message)
18350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    : data_(new AssertHelperData(type, file, line, message)) {
18360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
18370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
18380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgAssertHelper::~AssertHelper() {
18390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  delete data_;
18400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
18410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
18420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Message assignment, for assertion streaming support.
18430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid AssertHelper::operator=(const Message& message) const {
18440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  UnitTest::GetInstance()->
18450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    AddTestPartResult(data_->type, data_->file, data_->line,
18460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                      AppendUserMessage(data_->message, message),
18470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                      UnitTest::GetInstance()->impl()
18480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                      ->CurrentOsStackTraceExceptTop(1)
18490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                      // Skips the stack frame for this function itself.
18500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                      );  // NOLINT
18510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
18520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
18530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Mutex for linked pointers.
18540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgGTEST_API_ GTEST_DEFINE_STATIC_MUTEX_(g_linked_ptr_mutex);
18550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
18560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Application pathname gotten in InitGoogleTest.
18570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstd::string g_executable_path;
18580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
18590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Returns the current application's name, removing directory path if that
18600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// is present.
18610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgFilePath GetCurrentExecutableName() {
18620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  FilePath result;
18630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
18640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#if GTEST_OS_WINDOWS
18650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  result.Set(FilePath(g_executable_path).RemoveExtension("exe"));
18660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#else
18670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  result.Set(FilePath(g_executable_path));
18680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#endif  // GTEST_OS_WINDOWS
18690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
18700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return result.RemoveDirectoryName();
18710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
18720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
18730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Functions for processing the gtest_output flag.
18740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
18750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Returns the output format, or "" for normal printed output.
18760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstd::string UnitTestOptions::GetOutputFormat() {
18770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const char* const gtest_output_flag = GTEST_FLAG(output).c_str();
18780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (gtest_output_flag == NULL) return std::string("");
18790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
18800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const char* const colon = strchr(gtest_output_flag, ':');
18810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return (colon == NULL) ?
18820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      std::string(gtest_output_flag) :
18830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      std::string(gtest_output_flag, colon - gtest_output_flag);
18840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
18850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
18860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Returns the name of the requested output file, or the default if none
18870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// was explicitly specified.
18880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstd::string UnitTestOptions::GetAbsolutePathToOutputFile() {
18890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const char* const gtest_output_flag = GTEST_FLAG(output).c_str();
18900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (gtest_output_flag == NULL)
18910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return "";
18920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
18930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const char* const colon = strchr(gtest_output_flag, ':');
18940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (colon == NULL)
18950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return internal::FilePath::ConcatPaths(
18960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        internal::FilePath(
18970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org            UnitTest::GetInstance()->original_working_dir()),
18980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        internal::FilePath(kDefaultOutputFile)).string();
18990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
19000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  internal::FilePath output_name(colon + 1);
19010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (!output_name.IsAbsolutePath())
19020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // TODO(wan@google.com): on Windows \some\path is not an absolute
19030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // path (as its meaning depends on the current drive), yet the
19040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // following logic for turning it into an absolute path is wrong.
19050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // Fix it.
19060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    output_name = internal::FilePath::ConcatPaths(
19070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        internal::FilePath(UnitTest::GetInstance()->original_working_dir()),
19080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        internal::FilePath(colon + 1));
19090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
19100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (!output_name.IsDirectory())
19110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return output_name.string();
19120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
19130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  internal::FilePath result(internal::FilePath::GenerateUniqueFileName(
19140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      output_name, internal::GetCurrentExecutableName(),
19150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      GetOutputFormat().c_str()));
19160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return result.string();
19170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
19180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
19190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Returns true iff the wildcard pattern matches the string.  The
19200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// first ':' or '\0' character in pattern marks the end of it.
19210d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
19220d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// This recursive algorithm isn't very efficient, but is clear and
19230d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// works well enough for matching test names, which are short.
19240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgbool UnitTestOptions::PatternMatchesString(const char *pattern,
19250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                           const char *str) {
19260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  switch (*pattern) {
19270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    case '\0':
19280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    case ':':  // Either ':' or '\0' marks the end of the pattern.
19290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      return *str == '\0';
19300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    case '?':  // Matches any single character.
19310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      return *str != '\0' && PatternMatchesString(pattern + 1, str + 1);
19320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    case '*':  // Matches any string (possibly empty) of characters.
19330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      return (*str != '\0' && PatternMatchesString(pattern, str + 1)) ||
19340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          PatternMatchesString(pattern + 1, str);
19350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    default:  // Non-special character.  Matches itself.
19360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      return *pattern == *str &&
19370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          PatternMatchesString(pattern + 1, str + 1);
19380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
19390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
19400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
19410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgbool UnitTestOptions::MatchesFilter(
19420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const std::string& name, const char* filter) {
19430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const char *cur_pattern = filter;
19440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  for (;;) {
19450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    if (PatternMatchesString(cur_pattern, name.c_str())) {
19460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      return true;
19470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    }
19480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
19490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // Finds the next pattern in the filter.
19500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    cur_pattern = strchr(cur_pattern, ':');
19510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
19520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // Returns if no more pattern can be found.
19530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    if (cur_pattern == NULL) {
19540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      return false;
19550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    }
19560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
19570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // Skips the pattern separater (the ':' character).
19580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    cur_pattern++;
19590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
19600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
19610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
19620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Returns true iff the user-specified filter matches the test case
19630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// name and the test name.
19640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgbool UnitTestOptions::FilterMatchesTest(const std::string &test_case_name,
19650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                        const std::string &test_name) {
19660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const std::string& full_name = test_case_name + "." + test_name.c_str();
19670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
19680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Split --gtest_filter at '-', if there is one, to separate into
19690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // positive filter and negative filter portions
19700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const char* const p = GTEST_FLAG(filter).c_str();
19710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const char* const dash = strchr(p, '-');
19720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  std::string positive;
19730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  std::string negative;
19740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (dash == NULL) {
19750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    positive = GTEST_FLAG(filter).c_str();  // Whole string is a positive filter
19760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    negative = "";
19770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  } else {
19780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    positive = std::string(p, dash);   // Everything up to the dash
19790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    negative = std::string(dash + 1);  // Everything after the dash
19800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    if (positive.empty()) {
19810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      // Treat '-test1' as the same as '*-test1'
19820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      positive = kUniversalFilter;
19830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    }
19840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
19850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
19860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // A filter is a colon-separated list of patterns.  It matches a
19870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // test if any pattern in it matches the test.
19880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return (MatchesFilter(full_name, positive.c_str()) &&
19890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          !MatchesFilter(full_name, negative.c_str()));
19900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
19910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
19920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#if GTEST_HAS_SEH
19930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Returns EXCEPTION_EXECUTE_HANDLER if Google Test should handle the
19940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// given SEH exception, or EXCEPTION_CONTINUE_SEARCH otherwise.
19950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// This function is useful as an __except condition.
19960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgint UnitTestOptions::GTestShouldProcessSEH(DWORD exception_code) {
19970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Google Test should handle a SEH exception if:
19980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  //   1. the user wants it to, AND
19990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  //   2. this is not a breakpoint exception, AND
20000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  //   3. this is not a C++ exception (VC++ implements them via SEH,
20010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  //      apparently).
20020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  //
20030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // SEH exception code for C++ exceptions.
20040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // (see http://support.microsoft.com/kb/185294 for more information).
20050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const DWORD kCxxExceptionCode = 0xe06d7363;
20060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
20070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  bool should_handle = true;
20080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
20090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (!GTEST_FLAG(catch_exceptions))
20100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    should_handle = false;
20110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  else if (exception_code == EXCEPTION_BREAKPOINT)
20120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    should_handle = false;
20130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  else if (exception_code == kCxxExceptionCode)
20140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    should_handle = false;
20150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
20160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return should_handle ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH;
20170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
20180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#endif  // GTEST_HAS_SEH
20190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
20200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}  // namespace internal
20210d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
20220d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// The c'tor sets this object as the test part result reporter used by
20230d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Google Test.  The 'result' parameter specifies where to report the
20240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// results. Intercepts only failures from the current thread.
20250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgScopedFakeTestPartResultReporter::ScopedFakeTestPartResultReporter(
20260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    TestPartResultArray* result)
20270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    : intercept_mode_(INTERCEPT_ONLY_CURRENT_THREAD),
20280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      result_(result) {
20290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  Init();
20300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
20310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
20320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// The c'tor sets this object as the test part result reporter used by
20330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Google Test.  The 'result' parameter specifies where to report the
20340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// results.
20350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgScopedFakeTestPartResultReporter::ScopedFakeTestPartResultReporter(
20360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    InterceptMode intercept_mode, TestPartResultArray* result)
20370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    : intercept_mode_(intercept_mode),
20380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      result_(result) {
20390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  Init();
20400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
20410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
20420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid ScopedFakeTestPartResultReporter::Init() {
20430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  internal::UnitTestImpl* const impl = internal::GetUnitTestImpl();
20440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (intercept_mode_ == INTERCEPT_ALL_THREADS) {
20450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    old_reporter_ = impl->GetGlobalTestPartResultReporter();
20460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    impl->SetGlobalTestPartResultReporter(this);
20470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  } else {
20480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    old_reporter_ = impl->GetTestPartResultReporterForCurrentThread();
20490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    impl->SetTestPartResultReporterForCurrentThread(this);
20500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
20510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
20520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
20530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// The d'tor restores the test part result reporter used by Google Test
20540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// before.
20550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgScopedFakeTestPartResultReporter::~ScopedFakeTestPartResultReporter() {
20560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  internal::UnitTestImpl* const impl = internal::GetUnitTestImpl();
20570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (intercept_mode_ == INTERCEPT_ALL_THREADS) {
20580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    impl->SetGlobalTestPartResultReporter(old_reporter_);
20590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  } else {
20600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    impl->SetTestPartResultReporterForCurrentThread(old_reporter_);
20610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
20620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
20630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
20640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Increments the test part result count and remembers the result.
20650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// This method is from the TestPartResultReporterInterface interface.
20660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid ScopedFakeTestPartResultReporter::ReportTestPartResult(
20670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const TestPartResult& result) {
20680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  result_->Append(result);
20690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
20700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
20710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgnamespace internal {
20720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
20730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Returns the type ID of ::testing::Test.  We should always call this
20740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// instead of GetTypeId< ::testing::Test>() to get the type ID of
20750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// testing::Test.  This is to work around a suspected linker bug when
20760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// using Google Test as a framework on Mac OS X.  The bug causes
20770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// GetTypeId< ::testing::Test>() to return different values depending
20780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// on whether the call is from the Google Test framework itself or
20790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// from user test code.  GetTestTypeId() is guaranteed to always
20800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// return the same value, as it always calls GetTypeId<>() from the
20810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// gtest.cc, which is within the Google Test framework.
20820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgTypeId GetTestTypeId() {
20830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return GetTypeId<Test>();
20840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
20850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
20860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// The value of GetTestTypeId() as seen from within the Google Test
20870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// library.  This is solely for testing GetTestTypeId().
20880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgextern const TypeId kTestTypeIdInGoogleTest = GetTestTypeId();
20890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
20900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// This predicate-formatter checks that 'results' contains a test part
20910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// failure of the given type and that the failure message contains the
20920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// given substring.
20930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgAssertionResult HasOneFailure(const char* /* results_expr */,
20940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                              const char* /* type_expr */,
20950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                              const char* /* substr_expr */,
20960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                              const TestPartResultArray& results,
20970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                              TestPartResult::Type type,
20980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                              const string& substr) {
20990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const std::string expected(type == TestPartResult::kFatalFailure ?
21000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                        "1 fatal failure" :
21010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                        "1 non-fatal failure");
21020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  Message msg;
21030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (results.size() != 1) {
21040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    msg << "Expected: " << expected << "\n"
21050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        << "  Actual: " << results.size() << " failures";
21060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    for (int i = 0; i < results.size(); i++) {
21070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      msg << "\n" << results.GetTestPartResult(i);
21080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    }
21090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return AssertionFailure() << msg;
21100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
21110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
21120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const TestPartResult& r = results.GetTestPartResult(0);
21130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (r.type() != type) {
21140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return AssertionFailure() << "Expected: " << expected << "\n"
21150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                              << "  Actual:\n"
21160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                              << r;
21170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
21180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
21190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (strstr(r.message(), substr.c_str()) == NULL) {
21200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return AssertionFailure() << "Expected: " << expected << " containing \""
21210d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                              << substr << "\"\n"
21220d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                              << "  Actual:\n"
21230d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                              << r;
21240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
21250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
21260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return AssertionSuccess();
21270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
21280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
21290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// The constructor of SingleFailureChecker remembers where to look up
21300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// test part results, what type of failure we expect, and what
21310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// substring the failure message should contain.
21320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgSingleFailureChecker:: SingleFailureChecker(
21330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const TestPartResultArray* results,
21340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    TestPartResult::Type type,
21350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const string& substr)
21360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    : results_(results),
21370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      type_(type),
21380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      substr_(substr) {}
21390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
21400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// The destructor of SingleFailureChecker verifies that the given
21410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// TestPartResultArray contains exactly one failure that has the given
21420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// type and contains the given substring.  If that's not the case, a
21430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// non-fatal failure will be generated.
21440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgSingleFailureChecker::~SingleFailureChecker() {
21450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  EXPECT_PRED_FORMAT3(HasOneFailure, *results_, type_, substr_);
21460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
21470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
21480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgDefaultGlobalTestPartResultReporter::DefaultGlobalTestPartResultReporter(
21490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    UnitTestImpl* unit_test) : unit_test_(unit_test) {}
21500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
21510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid DefaultGlobalTestPartResultReporter::ReportTestPartResult(
21520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const TestPartResult& result) {
21530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  unit_test_->current_test_result()->AddTestPartResult(result);
21540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  unit_test_->listeners()->repeater()->OnTestPartResult(result);
21550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
21560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
21570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgDefaultPerThreadTestPartResultReporter::DefaultPerThreadTestPartResultReporter(
21580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    UnitTestImpl* unit_test) : unit_test_(unit_test) {}
21590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
21600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid DefaultPerThreadTestPartResultReporter::ReportTestPartResult(
21610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const TestPartResult& result) {
21620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  unit_test_->GetGlobalTestPartResultReporter()->ReportTestPartResult(result);
21630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
21640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
21650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Returns the global test part result reporter.
21660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgTestPartResultReporterInterface*
21670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgUnitTestImpl::GetGlobalTestPartResultReporter() {
21680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  internal::MutexLock lock(&global_test_part_result_reporter_mutex_);
21690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return global_test_part_result_repoter_;
21700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
21710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
21720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Sets the global test part result reporter.
21730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid UnitTestImpl::SetGlobalTestPartResultReporter(
21740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    TestPartResultReporterInterface* reporter) {
21750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  internal::MutexLock lock(&global_test_part_result_reporter_mutex_);
21760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  global_test_part_result_repoter_ = reporter;
21770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
21780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
21790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Returns the test part result reporter for the current thread.
21800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgTestPartResultReporterInterface*
21810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgUnitTestImpl::GetTestPartResultReporterForCurrentThread() {
21820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return per_thread_test_part_result_reporter_.get();
21830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
21840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
21850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Sets the test part result reporter for the current thread.
21860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid UnitTestImpl::SetTestPartResultReporterForCurrentThread(
21870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    TestPartResultReporterInterface* reporter) {
21880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  per_thread_test_part_result_reporter_.set(reporter);
21890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
21900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
21910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Gets the number of successful test cases.
21920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgint UnitTestImpl::successful_test_case_count() const {
21930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return CountIf(test_cases_, TestCasePassed);
21940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
21950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
21960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Gets the number of failed test cases.
21970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgint UnitTestImpl::failed_test_case_count() const {
21980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return CountIf(test_cases_, TestCaseFailed);
21990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
22000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
22010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Gets the number of all test cases.
22020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgint UnitTestImpl::total_test_case_count() const {
22030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return static_cast<int>(test_cases_.size());
22040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
22050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
22060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Gets the number of all test cases that contain at least one test
22070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// that should run.
22080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgint UnitTestImpl::test_case_to_run_count() const {
22090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return CountIf(test_cases_, ShouldRunTestCase);
22100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
22110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
22120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Gets the number of successful tests.
22130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgint UnitTestImpl::successful_test_count() const {
22140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return SumOverTestCaseList(test_cases_, &TestCase::successful_test_count);
22150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
22160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
22170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Gets the number of failed tests.
22180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgint UnitTestImpl::failed_test_count() const {
22190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return SumOverTestCaseList(test_cases_, &TestCase::failed_test_count);
22200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
22210d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
22220d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Gets the number of disabled tests that will be reported in the XML report.
22230d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgint UnitTestImpl::reportable_disabled_test_count() const {
22240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return SumOverTestCaseList(test_cases_,
22250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                             &TestCase::reportable_disabled_test_count);
22260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
22270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
22280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Gets the number of disabled tests.
22290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgint UnitTestImpl::disabled_test_count() const {
22300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return SumOverTestCaseList(test_cases_, &TestCase::disabled_test_count);
22310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
22320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
22330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Gets the number of tests to be printed in the XML report.
22340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgint UnitTestImpl::reportable_test_count() const {
22350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return SumOverTestCaseList(test_cases_, &TestCase::reportable_test_count);
22360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
22370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
22380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Gets the number of all tests.
22390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgint UnitTestImpl::total_test_count() const {
22400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return SumOverTestCaseList(test_cases_, &TestCase::total_test_count);
22410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
22420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
22430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Gets the number of tests that should run.
22440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgint UnitTestImpl::test_to_run_count() const {
22450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return SumOverTestCaseList(test_cases_, &TestCase::test_to_run_count);
22460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
22470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
22480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Returns the current OS stack trace as an std::string.
22490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
22500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// The maximum number of stack frames to be included is specified by
22510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// the gtest_stack_trace_depth flag.  The skip_count parameter
22520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// specifies the number of top frames to be skipped, which doesn't
22530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// count against the number of frames to be included.
22540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
22550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// For example, if Foo() calls Bar(), which in turn calls
22560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// CurrentOsStackTraceExceptTop(1), Foo() will be included in the
22570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// trace but Bar() and CurrentOsStackTraceExceptTop() won't.
22580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstd::string UnitTestImpl::CurrentOsStackTraceExceptTop(int skip_count) {
22590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  (void)skip_count;
22600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return "";
22610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
22620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
22630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Returns the current time in milliseconds.
22640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgTimeInMillis GetTimeInMillis() {
22650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#if GTEST_OS_WINDOWS_MOBILE || defined(__BORLANDC__)
22660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Difference between 1970-01-01 and 1601-01-01 in milliseconds.
22670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // http://analogous.blogspot.com/2005/04/epoch.html
22680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const TimeInMillis kJavaEpochToWinFileTimeDelta =
22690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    static_cast<TimeInMillis>(116444736UL) * 100000UL;
22700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const DWORD kTenthMicrosInMilliSecond = 10000;
22710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
22720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  SYSTEMTIME now_systime;
22730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  FILETIME now_filetime;
22740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  ULARGE_INTEGER now_int64;
22750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // TODO(kenton@google.com): Shouldn't this just use
22760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  //   GetSystemTimeAsFileTime()?
22770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  GetSystemTime(&now_systime);
22780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (SystemTimeToFileTime(&now_systime, &now_filetime)) {
22790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    now_int64.LowPart = now_filetime.dwLowDateTime;
22800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    now_int64.HighPart = now_filetime.dwHighDateTime;
22810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    now_int64.QuadPart = (now_int64.QuadPart / kTenthMicrosInMilliSecond) -
22820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      kJavaEpochToWinFileTimeDelta;
22830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return now_int64.QuadPart;
22840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
22850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return 0;
22860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#elif GTEST_OS_WINDOWS && !GTEST_HAS_GETTIMEOFDAY_
22870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  __timeb64 now;
22880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
22890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# ifdef _MSC_VER
22900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
22910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // MSVC 8 deprecates _ftime64(), so we want to suppress warning 4996
22920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // (deprecated function) there.
22930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // TODO(kenton@google.com): Use GetTickCount()?  Or use
22940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  //   SystemTimeToFileTime()
22950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#  pragma warning(push)          // Saves the current warning state.
22960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#  pragma warning(disable:4996)  // Temporarily disables warning 4996.
22970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  _ftime64(&now);
22980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#  pragma warning(pop)           // Restores the warning state.
22990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# else
23000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
23010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  _ftime64(&now);
23020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
23030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# endif  // _MSC_VER
23040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
23050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return static_cast<TimeInMillis>(now.time) * 1000 + now.millitm;
23060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#elif GTEST_HAS_GETTIMEOFDAY_
23070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  struct timeval now;
23080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  gettimeofday(&now, NULL);
23090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return static_cast<TimeInMillis>(now.tv_sec) * 1000 + now.tv_usec / 1000;
23100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#else
23110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# error "Don't know how to get the current time on your system."
23120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#endif
23130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
23140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
23150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Utilities
23160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
23170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// class String.
23180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
23190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#if GTEST_OS_WINDOWS_MOBILE
23200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Creates a UTF-16 wide string from the given ANSI string, allocating
23210d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// memory using new. The caller is responsible for deleting the return
23220d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// value using delete[]. Returns the wide string, or NULL if the
23230d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// input is NULL.
23240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgLPCWSTR String::AnsiToUtf16(const char* ansi) {
23250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (!ansi) return NULL;
23260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const int length = strlen(ansi);
23270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const int unicode_length =
23280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      MultiByteToWideChar(CP_ACP, 0, ansi, length,
23290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                          NULL, 0);
23300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  WCHAR* unicode = new WCHAR[unicode_length + 1];
23310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  MultiByteToWideChar(CP_ACP, 0, ansi, length,
23320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                      unicode, unicode_length);
23330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  unicode[unicode_length] = 0;
23340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return unicode;
23350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
23360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
23370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Creates an ANSI string from the given wide string, allocating
23380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// memory using new. The caller is responsible for deleting the return
23390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// value using delete[]. Returns the ANSI string, or NULL if the
23400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// input is NULL.
23410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgconst char* String::Utf16ToAnsi(LPCWSTR utf16_str)  {
23420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (!utf16_str) return NULL;
23430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const int ansi_length =
23440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      WideCharToMultiByte(CP_ACP, 0, utf16_str, -1,
23450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                          NULL, 0, NULL, NULL);
23460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  char* ansi = new char[ansi_length + 1];
23470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  WideCharToMultiByte(CP_ACP, 0, utf16_str, -1,
23480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                      ansi, ansi_length, NULL, NULL);
23490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  ansi[ansi_length] = 0;
23500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return ansi;
23510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
23520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
23530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#endif  // GTEST_OS_WINDOWS_MOBILE
23540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
23550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Compares two C strings.  Returns true iff they have the same content.
23560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
23570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Unlike strcmp(), this function can handle NULL argument(s).  A NULL
23580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// C string is considered different to any non-NULL C string,
23590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// including the empty string.
23600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgbool String::CStringEquals(const char * lhs, const char * rhs) {
23610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if ( lhs == NULL ) return rhs == NULL;
23620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
23630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if ( rhs == NULL ) return false;
23640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
23650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return strcmp(lhs, rhs) == 0;
23660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
23670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
23680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#if GTEST_HAS_STD_WSTRING || GTEST_HAS_GLOBAL_WSTRING
23690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
23700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Converts an array of wide chars to a narrow string using the UTF-8
23710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// encoding, and streams the result to the given Message object.
23720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstatic void StreamWideCharsToMessage(const wchar_t* wstr, size_t length,
23730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                     Message* msg) {
23740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  for (size_t i = 0; i != length; ) {  // NOLINT
23750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    if (wstr[i] != L'\0') {
23760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      *msg << WideStringToUtf8(wstr + i, static_cast<int>(length - i));
23770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      while (i != length && wstr[i] != L'\0')
23780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        i++;
23790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    } else {
23800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      *msg << '\0';
23810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      i++;
23820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    }
23830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
23840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
23850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
23860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#endif  // GTEST_HAS_STD_WSTRING || GTEST_HAS_GLOBAL_WSTRING
23870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
23880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}  // namespace internal
23890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
23900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Constructs an empty Message.
23910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// We allocate the stringstream separately because otherwise each use of
23920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// ASSERT/EXPECT in a procedure adds over 200 bytes to the procedure's
23930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// stack frame leading to huge stack frames in some cases; gcc does not reuse
23940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// the stack space.
23950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgMessage::Message() : ss_(new ::std::stringstream) {
23960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // By default, we want there to be enough precision when printing
23970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // a double to a Message.
23980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  *ss_ << std::setprecision(std::numeric_limits<double>::digits10 + 2);
23990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
24000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
24010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// These two overloads allow streaming a wide C string to a Message
24020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// using the UTF-8 encoding.
24030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgMessage& Message::operator <<(const wchar_t* wide_c_str) {
24040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return *this << internal::String::ShowWideCString(wide_c_str);
24050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
24060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgMessage& Message::operator <<(wchar_t* wide_c_str) {
24070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return *this << internal::String::ShowWideCString(wide_c_str);
24080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
24090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
24100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#if GTEST_HAS_STD_WSTRING
24110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Converts the given wide string to a narrow string using the UTF-8
24120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// encoding, and streams the result to this Message object.
24130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgMessage& Message::operator <<(const ::std::wstring& wstr) {
24140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  internal::StreamWideCharsToMessage(wstr.c_str(), wstr.length(), this);
24150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return *this;
24160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
24170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#endif  // GTEST_HAS_STD_WSTRING
24180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
24190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#if GTEST_HAS_GLOBAL_WSTRING
24200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Converts the given wide string to a narrow string using the UTF-8
24210d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// encoding, and streams the result to this Message object.
24220d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgMessage& Message::operator <<(const ::wstring& wstr) {
24230d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  internal::StreamWideCharsToMessage(wstr.c_str(), wstr.length(), this);
24240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return *this;
24250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
24260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#endif  // GTEST_HAS_GLOBAL_WSTRING
24270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
24280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Gets the text streamed to this object so far as an std::string.
24290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Each '\0' character in the buffer is replaced with "\\0".
24300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstd::string Message::GetString() const {
24310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return internal::StringStreamToString(ss_.get());
24320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
24330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
24340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// AssertionResult constructors.
24350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Used in EXPECT_TRUE/FALSE(assertion_result).
24360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgAssertionResult::AssertionResult(const AssertionResult& other)
24370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    : success_(other.success_),
24380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      message_(other.message_.get() != NULL ?
24390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org               new ::std::string(*other.message_) :
24400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org               static_cast< ::std::string*>(NULL)) {
24410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
24420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
24430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Returns the assertion's negation. Used with EXPECT/ASSERT_FALSE.
24440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgAssertionResult AssertionResult::operator!() const {
24450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  AssertionResult negation(!success_);
24460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (message_.get() != NULL)
24470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    negation << *message_;
24480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return negation;
24490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
24500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
24510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Makes a successful assertion result.
24520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgAssertionResult AssertionSuccess() {
24530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return AssertionResult(true);
24540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
24550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
24560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Makes a failed assertion result.
24570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgAssertionResult AssertionFailure() {
24580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return AssertionResult(false);
24590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
24600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
24610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Makes a failed assertion result with the given failure message.
24620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Deprecated; use AssertionFailure() << message.
24630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgAssertionResult AssertionFailure(const Message& message) {
24640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return AssertionFailure() << message;
24650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
24660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
24670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgnamespace internal {
24680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
24690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Constructs and returns the message for an equality assertion
24700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// (e.g. ASSERT_EQ, EXPECT_STREQ, etc) failure.
24710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
24720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// The first four parameters are the expressions used in the assertion
24730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// and their values, as strings.  For example, for ASSERT_EQ(foo, bar)
24740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// where foo is 5 and bar is 6, we have:
24750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
24760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//   expected_expression: "foo"
24770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//   actual_expression:   "bar"
24780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//   expected_value:      "5"
24790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//   actual_value:        "6"
24800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
24810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// The ignoring_case parameter is true iff the assertion is a
24820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// *_STRCASEEQ*.  When it's true, the string " (ignoring case)" will
24830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// be inserted into the message.
24840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgAssertionResult EqFailure(const char* expected_expression,
24850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                          const char* actual_expression,
24860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                          const std::string& expected_value,
24870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                          const std::string& actual_value,
24880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                          bool ignoring_case) {
24890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  Message msg;
24900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  msg << "Value of: " << actual_expression;
24910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (actual_value != actual_expression) {
24920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    msg << "\n  Actual: " << actual_value;
24930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
24940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
24950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  msg << "\nExpected: " << expected_expression;
24960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (ignoring_case) {
24970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    msg << " (ignoring case)";
24980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
24990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (expected_value != expected_expression) {
25000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    msg << "\nWhich is: " << expected_value;
25010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
25020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
25030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return AssertionFailure() << msg;
25040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
25050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
25060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Constructs a failure message for Boolean assertions such as EXPECT_TRUE.
25070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstd::string GetBoolAssertionFailureMessage(
25080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const AssertionResult& assertion_result,
25090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const char* expression_text,
25100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const char* actual_predicate_value,
25110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const char* expected_predicate_value) {
25120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const char* actual_message = assertion_result.message();
25130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  Message msg;
25140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  msg << "Value of: " << expression_text
25150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      << "\n  Actual: " << actual_predicate_value;
25160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (actual_message[0] != '\0')
25170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    msg << " (" << actual_message << ")";
25180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  msg << "\nExpected: " << expected_predicate_value;
25190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return msg.GetString();
25200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
25210d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
25220d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Helper function for implementing ASSERT_NEAR.
25230d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgAssertionResult DoubleNearPredFormat(const char* expr1,
25240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                     const char* expr2,
25250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                     const char* abs_error_expr,
25260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                     double val1,
25270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                     double val2,
25280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                     double abs_error) {
25290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const double diff = fabs(val1 - val2);
25300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (diff <= abs_error) return AssertionSuccess();
25310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
25320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // TODO(wan): do not print the value of an expression if it's
25330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // already a literal.
25340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return AssertionFailure()
25350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      << "The difference between " << expr1 << " and " << expr2
25360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      << " is " << diff << ", which exceeds " << abs_error_expr << ", where\n"
25370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      << expr1 << " evaluates to " << val1 << ",\n"
25380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      << expr2 << " evaluates to " << val2 << ", and\n"
25390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      << abs_error_expr << " evaluates to " << abs_error << ".";
25400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
25410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
25420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
25430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Helper template for implementing FloatLE() and DoubleLE().
25440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgtemplate <typename RawType>
25450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgAssertionResult FloatingPointLE(const char* expr1,
25460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                const char* expr2,
25470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                RawType val1,
25480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                RawType val2) {
25490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Returns success if val1 is less than val2,
25500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (val1 < val2) {
25510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return AssertionSuccess();
25520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
25530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
25540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // or if val1 is almost equal to val2.
25550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const FloatingPoint<RawType> lhs(val1), rhs(val2);
25560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (lhs.AlmostEquals(rhs)) {
25570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return AssertionSuccess();
25580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
25590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
25600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Note that the above two checks will both fail if either val1 or
25610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // val2 is NaN, as the IEEE floating-point standard requires that
25620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // any predicate involving a NaN must return false.
25630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
25640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  ::std::stringstream val1_ss;
25650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  val1_ss << std::setprecision(std::numeric_limits<RawType>::digits10 + 2)
25660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          << val1;
25670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
25680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  ::std::stringstream val2_ss;
25690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  val2_ss << std::setprecision(std::numeric_limits<RawType>::digits10 + 2)
25700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          << val2;
25710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
25720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return AssertionFailure()
25730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      << "Expected: (" << expr1 << ") <= (" << expr2 << ")\n"
25740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      << "  Actual: " << StringStreamToString(&val1_ss) << " vs "
25750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      << StringStreamToString(&val2_ss);
25760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
25770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
25780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}  // namespace internal
25790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
25800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Asserts that val1 is less than, or almost equal to, val2.  Fails
25810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// otherwise.  In particular, it fails if either val1 or val2 is NaN.
25820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgAssertionResult FloatLE(const char* expr1, const char* expr2,
25830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                        float val1, float val2) {
25840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return internal::FloatingPointLE<float>(expr1, expr2, val1, val2);
25850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
25860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
25870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Asserts that val1 is less than, or almost equal to, val2.  Fails
25880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// otherwise.  In particular, it fails if either val1 or val2 is NaN.
25890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgAssertionResult DoubleLE(const char* expr1, const char* expr2,
25900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                         double val1, double val2) {
25910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return internal::FloatingPointLE<double>(expr1, expr2, val1, val2);
25920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
25930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
25940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgnamespace internal {
25950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
25960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// The helper function for {ASSERT|EXPECT}_EQ with int or enum
25970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// arguments.
25980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgAssertionResult CmpHelperEQ(const char* expected_expression,
25990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                            const char* actual_expression,
26000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                            BiggestInt expected,
26010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                            BiggestInt actual) {
26020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (expected == actual) {
26030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return AssertionSuccess();
26040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
26050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
26060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return EqFailure(expected_expression,
26070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                   actual_expression,
26080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                   FormatForComparisonFailureMessage(expected, actual),
26090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                   FormatForComparisonFailureMessage(actual, expected),
26100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                   false);
26110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
26120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
26130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// A macro for implementing the helper functions needed to implement
26140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// ASSERT_?? and EXPECT_?? with integer or enum arguments.  It is here
26150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// just to avoid copy-and-paste of similar code.
26160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#define GTEST_IMPL_CMP_HELPER_(op_name, op)\
26170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgAssertionResult CmpHelper##op_name(const char* expr1, const char* expr2, \
26180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                   BiggestInt val1, BiggestInt val2) {\
26190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (val1 op val2) {\
26200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return AssertionSuccess();\
26210d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  } else {\
26220d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return AssertionFailure() \
26230d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        << "Expected: (" << expr1 << ") " #op " (" << expr2\
26240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        << "), actual: " << FormatForComparisonFailureMessage(val1, val2)\
26250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        << " vs " << FormatForComparisonFailureMessage(val2, val1);\
26260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }\
26270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
26280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
26290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Implements the helper function for {ASSERT|EXPECT}_NE with int or
26300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// enum arguments.
26310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgGTEST_IMPL_CMP_HELPER_(NE, !=)
26320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Implements the helper function for {ASSERT|EXPECT}_LE with int or
26330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// enum arguments.
26340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgGTEST_IMPL_CMP_HELPER_(LE, <=)
26350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Implements the helper function for {ASSERT|EXPECT}_LT with int or
26360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// enum arguments.
26370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgGTEST_IMPL_CMP_HELPER_(LT, < )
26380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Implements the helper function for {ASSERT|EXPECT}_GE with int or
26390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// enum arguments.
26400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgGTEST_IMPL_CMP_HELPER_(GE, >=)
26410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Implements the helper function for {ASSERT|EXPECT}_GT with int or
26420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// enum arguments.
26430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgGTEST_IMPL_CMP_HELPER_(GT, > )
26440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
26450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#undef GTEST_IMPL_CMP_HELPER_
26460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
26470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// The helper function for {ASSERT|EXPECT}_STREQ.
26480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgAssertionResult CmpHelperSTREQ(const char* expected_expression,
26490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                               const char* actual_expression,
26500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                               const char* expected,
26510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                               const char* actual) {
26520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (String::CStringEquals(expected, actual)) {
26530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return AssertionSuccess();
26540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
26550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
26560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return EqFailure(expected_expression,
26570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                   actual_expression,
26580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                   PrintToString(expected),
26590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                   PrintToString(actual),
26600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                   false);
26610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
26620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
26630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// The helper function for {ASSERT|EXPECT}_STRCASEEQ.
26640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgAssertionResult CmpHelperSTRCASEEQ(const char* expected_expression,
26650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                   const char* actual_expression,
26660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                   const char* expected,
26670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                   const char* actual) {
26680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (String::CaseInsensitiveCStringEquals(expected, actual)) {
26690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return AssertionSuccess();
26700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
26710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
26720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return EqFailure(expected_expression,
26730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                   actual_expression,
26740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                   PrintToString(expected),
26750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                   PrintToString(actual),
26760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                   true);
26770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
26780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
26790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// The helper function for {ASSERT|EXPECT}_STRNE.
26800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgAssertionResult CmpHelperSTRNE(const char* s1_expression,
26810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                               const char* s2_expression,
26820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                               const char* s1,
26830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                               const char* s2) {
26840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (!String::CStringEquals(s1, s2)) {
26850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return AssertionSuccess();
26860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  } else {
26870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return AssertionFailure() << "Expected: (" << s1_expression << ") != ("
26880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                              << s2_expression << "), actual: \""
26890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                              << s1 << "\" vs \"" << s2 << "\"";
26900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
26910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
26920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
26930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// The helper function for {ASSERT|EXPECT}_STRCASENE.
26940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgAssertionResult CmpHelperSTRCASENE(const char* s1_expression,
26950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                   const char* s2_expression,
26960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                   const char* s1,
26970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                   const char* s2) {
26980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (!String::CaseInsensitiveCStringEquals(s1, s2)) {
26990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return AssertionSuccess();
27000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  } else {
27010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return AssertionFailure()
27020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        << "Expected: (" << s1_expression << ") != ("
27030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        << s2_expression << ") (ignoring case), actual: \""
27040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        << s1 << "\" vs \"" << s2 << "\"";
27050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
27060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
27070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
27080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}  // namespace internal
27090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
27100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgnamespace {
27110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
27120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Helper functions for implementing IsSubString() and IsNotSubstring().
27130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
27140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// This group of overloaded functions return true iff needle is a
27150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// substring of haystack.  NULL is considered a substring of itself
27160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// only.
27170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
27180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgbool IsSubstringPred(const char* needle, const char* haystack) {
27190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (needle == NULL || haystack == NULL)
27200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return needle == haystack;
27210d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
27220d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return strstr(haystack, needle) != NULL;
27230d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
27240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
27250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgbool IsSubstringPred(const wchar_t* needle, const wchar_t* haystack) {
27260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (needle == NULL || haystack == NULL)
27270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return needle == haystack;
27280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
27290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return wcsstr(haystack, needle) != NULL;
27300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
27310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
27320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// StringType here can be either ::std::string or ::std::wstring.
27330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgtemplate <typename StringType>
27340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgbool IsSubstringPred(const StringType& needle,
27350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                     const StringType& haystack) {
27360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return haystack.find(needle) != StringType::npos;
27370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
27380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
27390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// This function implements either IsSubstring() or IsNotSubstring(),
27400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// depending on the value of the expected_to_be_substring parameter.
27410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// StringType here can be const char*, const wchar_t*, ::std::string,
27420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// or ::std::wstring.
27430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgtemplate <typename StringType>
27440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgAssertionResult IsSubstringImpl(
27450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    bool expected_to_be_substring,
27460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const char* needle_expr, const char* haystack_expr,
27470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const StringType& needle, const StringType& haystack) {
27480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (IsSubstringPred(needle, haystack) == expected_to_be_substring)
27490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return AssertionSuccess();
27500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
27510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const bool is_wide_string = sizeof(needle[0]) > 1;
27520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const char* const begin_string_quote = is_wide_string ? "L\"" : "\"";
27530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return AssertionFailure()
27540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      << "Value of: " << needle_expr << "\n"
27550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      << "  Actual: " << begin_string_quote << needle << "\"\n"
27560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      << "Expected: " << (expected_to_be_substring ? "" : "not ")
27570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      << "a substring of " << haystack_expr << "\n"
27580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      << "Which is: " << begin_string_quote << haystack << "\"";
27590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
27600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
27610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}  // namespace
27620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
27630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// IsSubstring() and IsNotSubstring() check whether needle is a
27640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// substring of haystack (NULL is considered a substring of itself
27650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// only), and return an appropriate error message when they fail.
27660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
27670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgAssertionResult IsSubstring(
27680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const char* needle_expr, const char* haystack_expr,
27690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const char* needle, const char* haystack) {
27700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack);
27710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
27720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
27730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgAssertionResult IsSubstring(
27740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const char* needle_expr, const char* haystack_expr,
27750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const wchar_t* needle, const wchar_t* haystack) {
27760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack);
27770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
27780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
27790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgAssertionResult IsNotSubstring(
27800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const char* needle_expr, const char* haystack_expr,
27810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const char* needle, const char* haystack) {
27820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack);
27830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
27840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
27850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgAssertionResult IsNotSubstring(
27860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const char* needle_expr, const char* haystack_expr,
27870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const wchar_t* needle, const wchar_t* haystack) {
27880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack);
27890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
27900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
27910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgAssertionResult IsSubstring(
27920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const char* needle_expr, const char* haystack_expr,
27930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const ::std::string& needle, const ::std::string& haystack) {
27940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack);
27950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
27960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
27970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgAssertionResult IsNotSubstring(
27980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const char* needle_expr, const char* haystack_expr,
27990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const ::std::string& needle, const ::std::string& haystack) {
28000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack);
28010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
28020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
28030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#if GTEST_HAS_STD_WSTRING
28040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgAssertionResult IsSubstring(
28050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const char* needle_expr, const char* haystack_expr,
28060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const ::std::wstring& needle, const ::std::wstring& haystack) {
28070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack);
28080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
28090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
28100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgAssertionResult IsNotSubstring(
28110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const char* needle_expr, const char* haystack_expr,
28120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const ::std::wstring& needle, const ::std::wstring& haystack) {
28130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack);
28140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
28150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#endif  // GTEST_HAS_STD_WSTRING
28160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
28170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgnamespace internal {
28180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
28190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#if GTEST_OS_WINDOWS
28200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
28210d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgnamespace {
28220d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
28230d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Helper function for IsHRESULT{SuccessFailure} predicates
28240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgAssertionResult HRESULTFailureHelper(const char* expr,
28250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                     const char* expected,
28260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                     long hr) {  // NOLINT
28270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# if GTEST_OS_WINDOWS_MOBILE
28280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
28290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Windows CE doesn't support FormatMessage.
28300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const char error_text[] = "";
28310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
28320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# else
28330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
28340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Looks up the human-readable system message for the HRESULT code
28350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // and since we're not passing any params to FormatMessage, we don't
28360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // want inserts expanded.
28370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const DWORD kFlags = FORMAT_MESSAGE_FROM_SYSTEM |
28380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                       FORMAT_MESSAGE_IGNORE_INSERTS;
28390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const DWORD kBufSize = 4096;
28400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Gets the system's human readable message string for this HRESULT.
28410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  char error_text[kBufSize] = { '\0' };
28420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  DWORD message_length = ::FormatMessageA(kFlags,
28430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                          0,  // no source, we're asking system
28440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                          hr,  // the error
28450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                          0,  // no line width restrictions
28460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                          error_text,  // output buffer
28470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                          kBufSize,  // buf size
28480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                          NULL);  // no arguments for inserts
28490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Trims tailing white space (FormatMessage leaves a trailing CR-LF)
28500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  for (; message_length && IsSpace(error_text[message_length - 1]);
28510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          --message_length) {
28520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    error_text[message_length - 1] = '\0';
28530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
28540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
28550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# endif  // GTEST_OS_WINDOWS_MOBILE
28560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
28570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const std::string error_hex("0x" + String::FormatHexInt(hr));
28580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return ::testing::AssertionFailure()
28590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      << "Expected: " << expr << " " << expected << ".\n"
28600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      << "  Actual: " << error_hex << " " << error_text << "\n";
28610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
28620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
28630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}  // namespace
28640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
28650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgAssertionResult IsHRESULTSuccess(const char* expr, long hr) {  // NOLINT
28660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (SUCCEEDED(hr)) {
28670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return AssertionSuccess();
28680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
28690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return HRESULTFailureHelper(expr, "succeeds", hr);
28700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
28710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
28720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgAssertionResult IsHRESULTFailure(const char* expr, long hr) {  // NOLINT
28730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (FAILED(hr)) {
28740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return AssertionSuccess();
28750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
28760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return HRESULTFailureHelper(expr, "fails", hr);
28770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
28780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
28790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#endif  // GTEST_OS_WINDOWS
28800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
28810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Utility functions for encoding Unicode text (wide strings) in
28820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// UTF-8.
28830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
28840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// A Unicode code-point can have upto 21 bits, and is encoded in UTF-8
28850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// like this:
28860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
28870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Code-point length   Encoding
28880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//   0 -  7 bits       0xxxxxxx
28890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//   8 - 11 bits       110xxxxx 10xxxxxx
28900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//  12 - 16 bits       1110xxxx 10xxxxxx 10xxxxxx
28910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//  17 - 21 bits       11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
28920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
28930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// The maximum code-point a one-byte UTF-8 sequence can represent.
28940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgconst UInt32 kMaxCodePoint1 = (static_cast<UInt32>(1) <<  7) - 1;
28950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
28960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// The maximum code-point a two-byte UTF-8 sequence can represent.
28970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgconst UInt32 kMaxCodePoint2 = (static_cast<UInt32>(1) << (5 + 6)) - 1;
28980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
28990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// The maximum code-point a three-byte UTF-8 sequence can represent.
29000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgconst UInt32 kMaxCodePoint3 = (static_cast<UInt32>(1) << (4 + 2*6)) - 1;
29010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
29020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// The maximum code-point a four-byte UTF-8 sequence can represent.
29030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgconst UInt32 kMaxCodePoint4 = (static_cast<UInt32>(1) << (3 + 3*6)) - 1;
29040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
29050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Chops off the n lowest bits from a bit pattern.  Returns the n
29060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// lowest bits.  As a side effect, the original bit pattern will be
29070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// shifted to the right by n bits.
29080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orginline UInt32 ChopLowBits(UInt32* bits, int n) {
29090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const UInt32 low_bits = *bits & ((static_cast<UInt32>(1) << n) - 1);
29100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  *bits >>= n;
29110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return low_bits;
29120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
29130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
29140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Converts a Unicode code point to a narrow string in UTF-8 encoding.
29150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// code_point parameter is of type UInt32 because wchar_t may not be
29160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// wide enough to contain a code point.
29170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// If the code_point is not a valid Unicode code point
29180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// (i.e. outside of Unicode range U+0 to U+10FFFF) it will be converted
29190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// to "(Invalid Unicode 0xXXXXXXXX)".
29200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstd::string CodePointToUtf8(UInt32 code_point) {
29210d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (code_point > kMaxCodePoint4) {
29220d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return "(Invalid Unicode 0x" + String::FormatHexInt(code_point) + ")";
29230d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
29240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
29250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  char str[5];  // Big enough for the largest valid code point.
29260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (code_point <= kMaxCodePoint1) {
29270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    str[1] = '\0';
29280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    str[0] = static_cast<char>(code_point);                          // 0xxxxxxx
29290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  } else if (code_point <= kMaxCodePoint2) {
29300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    str[2] = '\0';
29310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    str[1] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6));  // 10xxxxxx
29320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    str[0] = static_cast<char>(0xC0 | code_point);                   // 110xxxxx
29330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  } else if (code_point <= kMaxCodePoint3) {
29340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    str[3] = '\0';
29350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    str[2] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6));  // 10xxxxxx
29360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    str[1] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6));  // 10xxxxxx
29370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    str[0] = static_cast<char>(0xE0 | code_point);                   // 1110xxxx
29380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  } else {  // code_point <= kMaxCodePoint4
29390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    str[4] = '\0';
29400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    str[3] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6));  // 10xxxxxx
29410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    str[2] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6));  // 10xxxxxx
29420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    str[1] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6));  // 10xxxxxx
29430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    str[0] = static_cast<char>(0xF0 | code_point);                   // 11110xxx
29440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
29450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return str;
29460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
29470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
29480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// The following two functions only make sense if the the system
29490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// uses UTF-16 for wide string encoding. All supported systems
29500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// with 16 bit wchar_t (Windows, Cygwin, Symbian OS) do use UTF-16.
29510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
29520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Determines if the arguments constitute UTF-16 surrogate pair
29530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// and thus should be combined into a single Unicode code point
29540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// using CreateCodePointFromUtf16SurrogatePair.
29550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orginline bool IsUtf16SurrogatePair(wchar_t first, wchar_t second) {
29560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return sizeof(wchar_t) == 2 &&
29570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      (first & 0xFC00) == 0xD800 && (second & 0xFC00) == 0xDC00;
29580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
29590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
29600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Creates a Unicode code point from UTF16 surrogate pair.
29610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orginline UInt32 CreateCodePointFromUtf16SurrogatePair(wchar_t first,
29620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                                    wchar_t second) {
29630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const UInt32 mask = (1 << 10) - 1;
29640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return (sizeof(wchar_t) == 2) ?
29650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      (((first & mask) << 10) | (second & mask)) + 0x10000 :
29660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      // This function should not be called when the condition is
29670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      // false, but we provide a sensible default in case it is.
29680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      static_cast<UInt32>(first);
29690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
29700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
29710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Converts a wide string to a narrow string in UTF-8 encoding.
29720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// The wide string is assumed to have the following encoding:
29730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//   UTF-16 if sizeof(wchar_t) == 2 (on Windows, Cygwin, Symbian OS)
29740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//   UTF-32 if sizeof(wchar_t) == 4 (on Linux)
29750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Parameter str points to a null-terminated wide string.
29760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Parameter num_chars may additionally limit the number
29770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// of wchar_t characters processed. -1 is used when the entire string
29780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// should be processed.
29790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// If the string contains code points that are not valid Unicode code points
29800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// (i.e. outside of Unicode range U+0 to U+10FFFF) they will be output
29810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// as '(Invalid Unicode 0xXXXXXXXX)'. If the string is in UTF16 encoding
29820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// and contains invalid UTF-16 surrogate pairs, values in those pairs
29830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// will be encoded as individual Unicode characters from Basic Normal Plane.
29840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstd::string WideStringToUtf8(const wchar_t* str, int num_chars) {
29850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (num_chars == -1)
29860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    num_chars = static_cast<int>(wcslen(str));
29870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
29880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  ::std::stringstream stream;
29890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  for (int i = 0; i < num_chars; ++i) {
29900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    UInt32 unicode_code_point;
29910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
29920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    if (str[i] == L'\0') {
29930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      break;
29940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    } else if (i + 1 < num_chars && IsUtf16SurrogatePair(str[i], str[i + 1])) {
29950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      unicode_code_point = CreateCodePointFromUtf16SurrogatePair(str[i],
29960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                                                 str[i + 1]);
29970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      i++;
29980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    } else {
29990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      unicode_code_point = static_cast<UInt32>(str[i]);
30000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    }
30010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
30020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    stream << CodePointToUtf8(unicode_code_point);
30030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
30040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return StringStreamToString(&stream);
30050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
30060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
30070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Converts a wide C string to an std::string using the UTF-8 encoding.
30080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// NULL will be converted to "(null)".
30090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstd::string String::ShowWideCString(const wchar_t * wide_c_str) {
30100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (wide_c_str == NULL)  return "(null)";
30110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
30120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return internal::WideStringToUtf8(wide_c_str, -1);
30130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
30140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
30150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Compares two wide C strings.  Returns true iff they have the same
30160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// content.
30170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
30180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Unlike wcscmp(), this function can handle NULL argument(s).  A NULL
30190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// C string is considered different to any non-NULL C string,
30200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// including the empty string.
30210d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgbool String::WideCStringEquals(const wchar_t * lhs, const wchar_t * rhs) {
30220d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (lhs == NULL) return rhs == NULL;
30230d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
30240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (rhs == NULL) return false;
30250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
30260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return wcscmp(lhs, rhs) == 0;
30270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
30280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
30290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Helper function for *_STREQ on wide strings.
30300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgAssertionResult CmpHelperSTREQ(const char* expected_expression,
30310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                               const char* actual_expression,
30320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                               const wchar_t* expected,
30330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                               const wchar_t* actual) {
30340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (String::WideCStringEquals(expected, actual)) {
30350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return AssertionSuccess();
30360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
30370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
30380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return EqFailure(expected_expression,
30390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                   actual_expression,
30400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                   PrintToString(expected),
30410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                   PrintToString(actual),
30420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                   false);
30430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
30440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
30450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Helper function for *_STRNE on wide strings.
30460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgAssertionResult CmpHelperSTRNE(const char* s1_expression,
30470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                               const char* s2_expression,
30480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                               const wchar_t* s1,
30490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                               const wchar_t* s2) {
30500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (!String::WideCStringEquals(s1, s2)) {
30510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return AssertionSuccess();
30520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
30530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
30540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return AssertionFailure() << "Expected: (" << s1_expression << ") != ("
30550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                            << s2_expression << "), actual: "
30560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                            << PrintToString(s1)
30570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                            << " vs " << PrintToString(s2);
30580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
30590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
30600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Compares two C strings, ignoring case.  Returns true iff they have
30610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// the same content.
30620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
30630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Unlike strcasecmp(), this function can handle NULL argument(s).  A
30640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// NULL C string is considered different to any non-NULL C string,
30650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// including the empty string.
30660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgbool String::CaseInsensitiveCStringEquals(const char * lhs, const char * rhs) {
30670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (lhs == NULL)
30680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return rhs == NULL;
30690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (rhs == NULL)
30700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return false;
30710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return posix::StrCaseCmp(lhs, rhs) == 0;
30720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
30730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
30740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Compares two wide C strings, ignoring case.  Returns true iff they
30750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // have the same content.
30760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  //
30770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Unlike wcscasecmp(), this function can handle NULL argument(s).
30780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // A NULL C string is considered different to any non-NULL wide C string,
30790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // including the empty string.
30800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // NB: The implementations on different platforms slightly differ.
30810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // On windows, this method uses _wcsicmp which compares according to LC_CTYPE
30820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // environment variable. On GNU platform this method uses wcscasecmp
30830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // which compares according to LC_CTYPE category of the current locale.
30840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // On MacOS X, it uses towlower, which also uses LC_CTYPE category of the
30850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // current locale.
30860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgbool String::CaseInsensitiveWideCStringEquals(const wchar_t* lhs,
30870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                              const wchar_t* rhs) {
30880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (lhs == NULL) return rhs == NULL;
30890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
30900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (rhs == NULL) return false;
30910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
30920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#if GTEST_OS_WINDOWS
30930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return _wcsicmp(lhs, rhs) == 0;
30940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#elif GTEST_OS_LINUX && !GTEST_OS_LINUX_ANDROID
30950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return wcscasecmp(lhs, rhs) == 0;
30960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#else
30970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Android, Mac OS X and Cygwin don't define wcscasecmp.
30980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Other unknown OSes may not define it either.
30990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  wint_t left, right;
31000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  do {
31010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    left = towlower(*lhs++);
31020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    right = towlower(*rhs++);
31030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  } while (left && left == right);
31040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return left == right;
31050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#endif  // OS selector
31060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
31070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
31080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Returns true iff str ends with the given suffix, ignoring case.
31090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Any string is considered to end with an empty suffix.
31100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgbool String::EndsWithCaseInsensitive(
31110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const std::string& str, const std::string& suffix) {
31120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const size_t str_len = str.length();
31130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const size_t suffix_len = suffix.length();
31140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return (str_len >= suffix_len) &&
31150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org         CaseInsensitiveCStringEquals(str.c_str() + str_len - suffix_len,
31160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                      suffix.c_str());
31170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
31180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
31190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Formats an int value as "%02d".
31200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstd::string String::FormatIntWidth2(int value) {
31210d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  std::stringstream ss;
31220d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  ss << std::setfill('0') << std::setw(2) << value;
31230d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return ss.str();
31240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
31250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
31260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Formats an int value as "%X".
31270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstd::string String::FormatHexInt(int value) {
31280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  std::stringstream ss;
31290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  ss << std::hex << std::uppercase << value;
31300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return ss.str();
31310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
31320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
31330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Formats a byte as "%02X".
31340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstd::string String::FormatByte(unsigned char value) {
31350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  std::stringstream ss;
31360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  ss << std::setfill('0') << std::setw(2) << std::hex << std::uppercase
31370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org     << static_cast<unsigned int>(value);
31380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return ss.str();
31390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
31400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
31410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Converts the buffer in a stringstream to an std::string, converting NUL
31420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// bytes to "\\0" along the way.
31430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstd::string StringStreamToString(::std::stringstream* ss) {
31440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const ::std::string& str = ss->str();
31450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const char* const start = str.c_str();
31460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const char* const end = start + str.length();
31470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
31480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  std::string result;
31490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  result.reserve(2 * (end - start));
31500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  for (const char* ch = start; ch != end; ++ch) {
31510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    if (*ch == '\0') {
31520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      result += "\\0";  // Replaces NUL with "\\0";
31530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    } else {
31540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      result += *ch;
31550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    }
31560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
31570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
31580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return result;
31590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
31600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
31610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Appends the user-supplied message to the Google-Test-generated message.
31620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstd::string AppendUserMessage(const std::string& gtest_msg,
31630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                              const Message& user_msg) {
31640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Appends the user message if it's non-empty.
31650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const std::string user_msg_string = user_msg.GetString();
31660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (user_msg_string.empty()) {
31670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return gtest_msg;
31680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
31690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
31700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return gtest_msg + "\n" + user_msg_string;
31710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
31720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
31730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}  // namespace internal
31740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
31750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// class TestResult
31760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
31770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Creates an empty TestResult.
31780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgTestResult::TestResult()
31790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    : death_test_count_(0),
31800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      elapsed_time_(0) {
31810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
31820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
31830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// D'tor.
31840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgTestResult::~TestResult() {
31850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
31860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
31870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Returns the i-th test part result among all the results. i can
31880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// range from 0 to total_part_count() - 1. If i is not in that range,
31890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// aborts the program.
31900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgconst TestPartResult& TestResult::GetTestPartResult(int i) const {
31910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (i < 0 || i >= total_part_count())
31920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    internal::posix::Abort();
31930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return test_part_results_.at(i);
31940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
31950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
31960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Returns the i-th test property. i can range from 0 to
31970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// test_property_count() - 1. If i is not in that range, aborts the
31980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// program.
31990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgconst TestProperty& TestResult::GetTestProperty(int i) const {
32000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (i < 0 || i >= test_property_count())
32010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    internal::posix::Abort();
32020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return test_properties_.at(i);
32030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
32040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
32050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Clears the test part results.
32060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid TestResult::ClearTestPartResults() {
32070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  test_part_results_.clear();
32080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
32090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
32100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Adds a test part result to the list.
32110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid TestResult::AddTestPartResult(const TestPartResult& test_part_result) {
32120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  test_part_results_.push_back(test_part_result);
32130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
32140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
32150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Adds a test property to the list. If a property with the same key as the
32160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// supplied property is already represented, the value of this test_property
32170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// replaces the old value for that key.
32180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid TestResult::RecordProperty(const std::string& xml_element,
32190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                const TestProperty& test_property) {
32200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (!ValidateTestProperty(xml_element, test_property)) {
32210d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return;
32220d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
32230d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  internal::MutexLock lock(&test_properites_mutex_);
32240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const std::vector<TestProperty>::iterator property_with_matching_key =
32250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      std::find_if(test_properties_.begin(), test_properties_.end(),
32260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                   internal::TestPropertyKeyIs(test_property.key()));
32270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (property_with_matching_key == test_properties_.end()) {
32280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    test_properties_.push_back(test_property);
32290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return;
32300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
32310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  property_with_matching_key->SetValue(test_property.value());
32320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
32330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
32340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// The list of reserved attributes used in the <testsuites> element of XML
32350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// output.
32360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstatic const char* const kReservedTestSuitesAttributes[] = {
32370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  "disabled",
32380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  "errors",
32390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  "failures",
32400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  "name",
32410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  "random_seed",
32420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  "tests",
32430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  "time",
32440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  "timestamp"
32450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org};
32460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
32470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// The list of reserved attributes used in the <testsuite> element of XML
32480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// output.
32490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstatic const char* const kReservedTestSuiteAttributes[] = {
32500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  "disabled",
32510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  "errors",
32520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  "failures",
32530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  "name",
32540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  "tests",
32550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  "time"
32560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org};
32570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
32580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// The list of reserved attributes used in the <testcase> element of XML output.
32590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstatic const char* const kReservedTestCaseAttributes[] = {
32600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  "classname",
32610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  "name",
32620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  "status",
32630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  "time",
32640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  "type_param",
32650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  "value_param"
32660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org};
32670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
32680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgtemplate <int kSize>
32690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstd::vector<std::string> ArrayAsVector(const char* const (&array)[kSize]) {
32700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return std::vector<std::string>(array, array + kSize);
32710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
32720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
32730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstatic std::vector<std::string> GetReservedAttributesForElement(
32740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const std::string& xml_element) {
32750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (xml_element == "testsuites") {
32760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return ArrayAsVector(kReservedTestSuitesAttributes);
32770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  } else if (xml_element == "testsuite") {
32780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return ArrayAsVector(kReservedTestSuiteAttributes);
32790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  } else if (xml_element == "testcase") {
32800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return ArrayAsVector(kReservedTestCaseAttributes);
32810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  } else {
32820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    GTEST_CHECK_(false) << "Unrecognized xml_element provided: " << xml_element;
32830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
32840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // This code is unreachable but some compilers may not realizes that.
32850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return std::vector<std::string>();
32860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
32870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
32880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstatic std::string FormatWordList(const std::vector<std::string>& words) {
32890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  Message word_list;
32900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  for (size_t i = 0; i < words.size(); ++i) {
32910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    if (i > 0 && words.size() > 2) {
32920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      word_list << ", ";
32930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    }
32940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    if (i == words.size() - 1) {
32950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      word_list << "and ";
32960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    }
32970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    word_list << "'" << words[i] << "'";
32980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
32990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return word_list.GetString();
33000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
33010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
33020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgbool ValidateTestPropertyName(const std::string& property_name,
33030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                              const std::vector<std::string>& reserved_names) {
33040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (std::find(reserved_names.begin(), reserved_names.end(), property_name) !=
33050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          reserved_names.end()) {
33060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    ADD_FAILURE() << "Reserved key used in RecordProperty(): " << property_name
33070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                  << " (" << FormatWordList(reserved_names)
33080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                  << " are reserved by " << GTEST_NAME_ << ")";
33090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return false;
33100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
33110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return true;
33120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
33130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
33140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Adds a failure if the key is a reserved attribute of the element named
33150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// xml_element.  Returns true if the property is valid.
33160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgbool TestResult::ValidateTestProperty(const std::string& xml_element,
33170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                      const TestProperty& test_property) {
33180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return ValidateTestPropertyName(test_property.key(),
33190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                  GetReservedAttributesForElement(xml_element));
33200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
33210d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
33220d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Clears the object.
33230d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid TestResult::Clear() {
33240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  test_part_results_.clear();
33250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  test_properties_.clear();
33260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  death_test_count_ = 0;
33270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  elapsed_time_ = 0;
33280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
33290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
33300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Returns true iff the test failed.
33310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgbool TestResult::Failed() const {
33320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  for (int i = 0; i < total_part_count(); ++i) {
33330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    if (GetTestPartResult(i).failed())
33340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      return true;
33350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
33360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return false;
33370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
33380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
33390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Returns true iff the test part fatally failed.
33400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstatic bool TestPartFatallyFailed(const TestPartResult& result) {
33410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return result.fatally_failed();
33420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
33430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
33440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Returns true iff the test fatally failed.
33450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgbool TestResult::HasFatalFailure() const {
33460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return CountIf(test_part_results_, TestPartFatallyFailed) > 0;
33470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
33480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
33490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Returns true iff the test part non-fatally failed.
33500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstatic bool TestPartNonfatallyFailed(const TestPartResult& result) {
33510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return result.nonfatally_failed();
33520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
33530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
33540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Returns true iff the test has a non-fatal failure.
33550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgbool TestResult::HasNonfatalFailure() const {
33560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return CountIf(test_part_results_, TestPartNonfatallyFailed) > 0;
33570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
33580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
33590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Gets the number of all test parts.  This is the sum of the number
33600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// of successful test parts and the number of failed test parts.
33610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgint TestResult::total_part_count() const {
33620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return static_cast<int>(test_part_results_.size());
33630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
33640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
33650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Returns the number of the test properties.
33660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgint TestResult::test_property_count() const {
33670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return static_cast<int>(test_properties_.size());
33680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
33690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
33700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// class Test
33710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
33720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Creates a Test object.
33730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
33740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// The c'tor saves the values of all Google Test flags.
33750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgTest::Test()
33760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    : gtest_flag_saver_(new internal::GTestFlagSaver) {
33770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
33780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
33790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// The d'tor restores the values of all Google Test flags.
33800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgTest::~Test() {
33810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  delete gtest_flag_saver_;
33820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
33830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
33840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Sets up the test fixture.
33850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
33860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// A sub-class may override this.
33870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid Test::SetUp() {
33880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
33890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
33900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Tears down the test fixture.
33910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
33920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// A sub-class may override this.
33930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid Test::TearDown() {
33940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
33950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
33960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Allows user supplied key value pairs to be recorded for later output.
33970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid Test::RecordProperty(const std::string& key, const std::string& value) {
33980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  UnitTest::GetInstance()->RecordProperty(key, value);
33990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
34000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
34010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Allows user supplied key value pairs to be recorded for later output.
34020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid Test::RecordProperty(const std::string& key, int value) {
34030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  Message value_message;
34040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  value_message << value;
34050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  RecordProperty(key, value_message.GetString().c_str());
34060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
34070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
34080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgnamespace internal {
34090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
34100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid ReportFailureInUnknownLocation(TestPartResult::Type result_type,
34110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                    const std::string& message) {
34120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // This function is a friend of UnitTest and as such has access to
34130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // AddTestPartResult.
34140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  UnitTest::GetInstance()->AddTestPartResult(
34150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      result_type,
34160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      NULL,  // No info about the source file where the exception occurred.
34170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      -1,    // We have no info on which line caused the exception.
34180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      message,
34190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      "");   // No stack trace, either.
34200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
34210d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
34220d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}  // namespace internal
34230d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
34240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Google Test requires all tests in the same test case to use the same test
34250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// fixture class.  This function checks if the current test has the
34260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// same fixture class as the first test in the current test case.  If
34270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// yes, it returns true; otherwise it generates a Google Test failure and
34280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// returns false.
34290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgbool Test::HasSameFixtureClass() {
34300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  internal::UnitTestImpl* const impl = internal::GetUnitTestImpl();
34310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const TestCase* const test_case = impl->current_test_case();
34320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
34330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Info about the first test in the current test case.
34340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const TestInfo* const first_test_info = test_case->test_info_list()[0];
34350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const internal::TypeId first_fixture_id = first_test_info->fixture_class_id_;
34360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const char* const first_test_name = first_test_info->name();
34370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
34380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Info about the current test.
34390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const TestInfo* const this_test_info = impl->current_test_info();
34400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const internal::TypeId this_fixture_id = this_test_info->fixture_class_id_;
34410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const char* const this_test_name = this_test_info->name();
34420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
34430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (this_fixture_id != first_fixture_id) {
34440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // Is the first test defined using TEST?
34450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const bool first_is_TEST = first_fixture_id == internal::GetTestTypeId();
34460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // Is this test defined using TEST?
34470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const bool this_is_TEST = this_fixture_id == internal::GetTestTypeId();
34480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
34490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    if (first_is_TEST || this_is_TEST) {
34500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      // The user mixed TEST and TEST_F in this test case - we'll tell
34510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      // him/her how to fix it.
34520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
34530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      // Gets the name of the TEST and the name of the TEST_F.  Note
34540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      // that first_is_TEST and this_is_TEST cannot both be true, as
34550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      // the fixture IDs are different for the two tests.
34560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      const char* const TEST_name =
34570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          first_is_TEST ? first_test_name : this_test_name;
34580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      const char* const TEST_F_name =
34590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          first_is_TEST ? this_test_name : first_test_name;
34600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
34610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      ADD_FAILURE()
34620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          << "All tests in the same test case must use the same test fixture\n"
34630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          << "class, so mixing TEST_F and TEST in the same test case is\n"
34640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          << "illegal.  In test case " << this_test_info->test_case_name()
34650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          << ",\n"
34660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          << "test " << TEST_F_name << " is defined using TEST_F but\n"
34670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          << "test " << TEST_name << " is defined using TEST.  You probably\n"
34680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          << "want to change the TEST to TEST_F or move it to another test\n"
34690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          << "case.";
34700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    } else {
34710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      // The user defined two fixture classes with the same name in
34720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      // two namespaces - we'll tell him/her how to fix it.
34730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      ADD_FAILURE()
34740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          << "All tests in the same test case must use the same test fixture\n"
34750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          << "class.  However, in test case "
34760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          << this_test_info->test_case_name() << ",\n"
34770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          << "you defined test " << first_test_name
34780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          << " and test " << this_test_name << "\n"
34790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          << "using two different test fixture classes.  This can happen if\n"
34800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          << "the two classes are from different namespaces or translation\n"
34810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          << "units and have the same name.  You should probably rename one\n"
34820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          << "of the classes to put the tests into different test cases.";
34830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    }
34840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return false;
34850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
34860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
34870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return true;
34880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
34890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
34900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#if GTEST_HAS_SEH
34910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
34920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Adds an "exception thrown" fatal failure to the current test.  This
34930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// function returns its result via an output parameter pointer because VC++
34940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// prohibits creation of objects with destructors on stack in functions
34950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// using __try (see error C2712).
34960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstatic std::string* FormatSehExceptionMessage(DWORD exception_code,
34970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                              const char* location) {
34980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  Message message;
34990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  message << "SEH exception with code 0x" << std::setbase(16) <<
35000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    exception_code << std::setbase(10) << " thrown in " << location << ".";
35010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
35020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return new std::string(message.GetString());
35030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
35040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
35050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#endif  // GTEST_HAS_SEH
35060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
35070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgnamespace internal {
35080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
35090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#if GTEST_HAS_EXCEPTIONS
35100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
35110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Adds an "exception thrown" fatal failure to the current test.
35120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstatic std::string FormatCxxExceptionMessage(const char* description,
35130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                             const char* location) {
35140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  Message message;
35150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (description != NULL) {
35160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    message << "C++ exception with description \"" << description << "\"";
35170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  } else {
35180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    message << "Unknown C++ exception";
35190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
35200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  message << " thrown in " << location << ".";
35210d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
35220d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return message.GetString();
35230d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
35240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
35250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstatic std::string PrintTestPartResultToString(
35260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const TestPartResult& test_part_result);
35270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
35280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgGoogleTestFailureException::GoogleTestFailureException(
35290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const TestPartResult& failure)
35300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    : ::std::runtime_error(PrintTestPartResultToString(failure).c_str()) {}
35310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
35320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#endif  // GTEST_HAS_EXCEPTIONS
35330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
35340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// We put these helper functions in the internal namespace as IBM's xlC
35350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// compiler rejects the code if they were declared static.
35360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
35370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Runs the given method and handles SEH exceptions it throws, when
35380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// SEH is supported; returns the 0-value for type Result in case of an
35390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// SEH exception.  (Microsoft compilers cannot handle SEH and C++
35400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// exceptions in the same function.  Therefore, we provide a separate
35410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// wrapper function for handling SEH exceptions.)
35420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgtemplate <class T, typename Result>
35430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgResult HandleSehExceptionsInMethodIfSupported(
35440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    T* object, Result (T::*method)(), const char* location) {
35450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#if GTEST_HAS_SEH
35460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  __try {
35470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return (object->*method)();
35480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  } __except (internal::UnitTestOptions::GTestShouldProcessSEH(  // NOLINT
35490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      GetExceptionCode())) {
35500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // We create the exception message on the heap because VC++ prohibits
35510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // creation of objects with destructors on stack in functions using __try
35520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // (see error C2712).
35530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    std::string* exception_message = FormatSehExceptionMessage(
35540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        GetExceptionCode(), location);
35550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    internal::ReportFailureInUnknownLocation(TestPartResult::kFatalFailure,
35560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                             *exception_message);
35570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    delete exception_message;
35580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return static_cast<Result>(0);
35590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
35600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#else
35610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  (void)location;
35620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return (object->*method)();
35630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#endif  // GTEST_HAS_SEH
35640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
35650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
35660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Runs the given method and catches and reports C++ and/or SEH-style
35670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// exceptions, if they are supported; returns the 0-value for type
35680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Result in case of an SEH exception.
35690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgtemplate <class T, typename Result>
35700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgResult HandleExceptionsInMethodIfSupported(
35710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    T* object, Result (T::*method)(), const char* location) {
35720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // NOTE: The user code can affect the way in which Google Test handles
35730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // exceptions by setting GTEST_FLAG(catch_exceptions), but only before
35740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // RUN_ALL_TESTS() starts. It is technically possible to check the flag
35750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // after the exception is caught and either report or re-throw the
35760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // exception based on the flag's value:
35770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  //
35780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // try {
35790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  //   // Perform the test method.
35800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // } catch (...) {
35810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  //   if (GTEST_FLAG(catch_exceptions))
35820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  //     // Report the exception as failure.
35830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  //   else
35840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  //     throw;  // Re-throws the original exception.
35850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // }
35860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  //
35870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // However, the purpose of this flag is to allow the program to drop into
35880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // the debugger when the exception is thrown. On most platforms, once the
35890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // control enters the catch block, the exception origin information is
35900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // lost and the debugger will stop the program at the point of the
35910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // re-throw in this function -- instead of at the point of the original
35920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // throw statement in the code under test.  For this reason, we perform
35930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // the check early, sacrificing the ability to affect Google Test's
35940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // exception handling in the method where the exception is thrown.
35950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (internal::GetUnitTestImpl()->catch_exceptions()) {
35960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#if GTEST_HAS_EXCEPTIONS
35970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    try {
35980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      return HandleSehExceptionsInMethodIfSupported(object, method, location);
35990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    } catch (const internal::GoogleTestFailureException&) {  // NOLINT
36000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      // This exception type can only be thrown by a failed Google
36010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      // Test assertion with the intention of letting another testing
36020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      // framework catch it.  Therefore we just re-throw it.
36030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      throw;
36040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    } catch (const std::exception& e) {  // NOLINT
36050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      internal::ReportFailureInUnknownLocation(
36060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          TestPartResult::kFatalFailure,
36070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          FormatCxxExceptionMessage(e.what(), location));
36080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    } catch (...) {  // NOLINT
36090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      internal::ReportFailureInUnknownLocation(
36100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          TestPartResult::kFatalFailure,
36110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          FormatCxxExceptionMessage(NULL, location));
36120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    }
36130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return static_cast<Result>(0);
36140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#else
36150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return HandleSehExceptionsInMethodIfSupported(object, method, location);
36160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#endif  // GTEST_HAS_EXCEPTIONS
36170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  } else {
36180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return (object->*method)();
36190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
36200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
36210d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
36220d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}  // namespace internal
36230d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
36240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Runs the test and updates the test result.
36250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid Test::Run() {
36260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (!HasSameFixtureClass()) return;
36270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
36280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  internal::UnitTestImpl* const impl = internal::GetUnitTestImpl();
36290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  impl->os_stack_trace_getter()->UponLeavingGTest();
36300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  internal::HandleExceptionsInMethodIfSupported(this, &Test::SetUp, "SetUp()");
36310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // We will run the test only if SetUp() was successful.
36320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (!HasFatalFailure()) {
36330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    impl->os_stack_trace_getter()->UponLeavingGTest();
36340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    internal::HandleExceptionsInMethodIfSupported(
36350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        this, &Test::TestBody, "the test body");
36360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
36370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
36380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // However, we want to clean up as much as possible.  Hence we will
36390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // always call TearDown(), even if SetUp() or the test body has
36400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // failed.
36410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  impl->os_stack_trace_getter()->UponLeavingGTest();
36420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  internal::HandleExceptionsInMethodIfSupported(
36430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      this, &Test::TearDown, "TearDown()");
36440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
36450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
36460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Returns true iff the current test has a fatal failure.
36470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgbool Test::HasFatalFailure() {
36480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return internal::GetUnitTestImpl()->current_test_result()->HasFatalFailure();
36490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
36500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
36510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Returns true iff the current test has a non-fatal failure.
36520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgbool Test::HasNonfatalFailure() {
36530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return internal::GetUnitTestImpl()->current_test_result()->
36540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      HasNonfatalFailure();
36550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
36560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
36570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// class TestInfo
36580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
36590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Constructs a TestInfo object. It assumes ownership of the test factory
36600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// object.
36610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgTestInfo::TestInfo(const std::string& a_test_case_name,
36620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                   const std::string& a_name,
36630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                   const char* a_type_param,
36640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                   const char* a_value_param,
36650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                   internal::TypeId fixture_class_id,
36660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                   internal::TestFactoryBase* factory)
36670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    : test_case_name_(a_test_case_name),
36680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      name_(a_name),
36690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      type_param_(a_type_param ? new std::string(a_type_param) : NULL),
36700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      value_param_(a_value_param ? new std::string(a_value_param) : NULL),
36710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      fixture_class_id_(fixture_class_id),
36720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      should_run_(false),
36730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      is_disabled_(false),
36740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      matches_filter_(false),
36750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      factory_(factory),
36760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      result_() {}
36770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
36780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Destructs a TestInfo object.
36790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgTestInfo::~TestInfo() { delete factory_; }
36800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
36810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgnamespace internal {
36820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
36830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Creates a new TestInfo object and registers it with Google Test;
36840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// returns the created object.
36850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
36860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Arguments:
36870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
36880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//   test_case_name:   name of the test case
36890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//   name:             name of the test
36900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//   type_param:       the name of the test's type parameter, or NULL if
36910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//                     this is not a typed or a type-parameterized test.
36920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//   value_param:      text representation of the test's value parameter,
36930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//                     or NULL if this is not a value-parameterized test.
36940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//   fixture_class_id: ID of the test fixture class
36950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//   set_up_tc:        pointer to the function that sets up the test case
36960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//   tear_down_tc:     pointer to the function that tears down the test case
36970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//   factory:          pointer to the factory that creates a test object.
36980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//                     The newly created TestInfo instance will assume
36990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//                     ownership of the factory object.
37000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgTestInfo* MakeAndRegisterTestInfo(
37010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const char* test_case_name,
37020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const char* name,
37030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const char* type_param,
37040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const char* value_param,
37050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    TypeId fixture_class_id,
37060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    SetUpTestCaseFunc set_up_tc,
37070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    TearDownTestCaseFunc tear_down_tc,
37080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    TestFactoryBase* factory) {
37090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  TestInfo* const test_info =
37100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      new TestInfo(test_case_name, name, type_param, value_param,
37110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                   fixture_class_id, factory);
37120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  GetUnitTestImpl()->AddTestInfo(set_up_tc, tear_down_tc, test_info);
37130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return test_info;
37140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
37150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
37160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#if GTEST_HAS_PARAM_TEST
37170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid ReportInvalidTestCaseType(const char* test_case_name,
37180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                               const char* file, int line) {
37190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  Message errors;
37200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  errors
37210d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      << "Attempted redefinition of test case " << test_case_name << ".\n"
37220d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      << "All tests in the same test case must use the same test fixture\n"
37230d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      << "class.  However, in test case " << test_case_name << ", you tried\n"
37240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      << "to define a test using a fixture class different from the one\n"
37250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      << "used earlier. This can happen if the two fixture classes are\n"
37260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      << "from different namespaces and have the same name. You should\n"
37270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      << "probably rename one of the classes to put the tests into different\n"
37280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      << "test cases.";
37290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
37300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  fprintf(stderr, "%s %s", FormatFileLocation(file, line).c_str(),
37310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          errors.GetString().c_str());
37320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
37330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#endif  // GTEST_HAS_PARAM_TEST
37340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
37350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}  // namespace internal
37360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
37370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgnamespace {
37380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
37390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// A predicate that checks the test name of a TestInfo against a known
37400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// value.
37410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
37420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// This is used for implementation of the TestCase class only.  We put
37430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// it in the anonymous namespace to prevent polluting the outer
37440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// namespace.
37450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
37460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// TestNameIs is copyable.
37470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgclass TestNameIs {
37480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org public:
37490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Constructor.
37500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  //
37510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // TestNameIs has NO default constructor.
37520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  explicit TestNameIs(const char* name)
37530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      : name_(name) {}
37540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
37550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Returns true iff the test name of test_info matches name_.
37560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  bool operator()(const TestInfo * test_info) const {
37570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return test_info && test_info->name() == name_;
37580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
37590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
37600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org private:
37610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  std::string name_;
37620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org};
37630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
37640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}  // namespace
37650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
37660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgnamespace internal {
37670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
37680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// This method expands all parameterized tests registered with macros TEST_P
37690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// and INSTANTIATE_TEST_CASE_P into regular tests and registers those.
37700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// This will be done just once during the program runtime.
37710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid UnitTestImpl::RegisterParameterizedTests() {
37720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#if GTEST_HAS_PARAM_TEST
37730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (!parameterized_tests_registered_) {
37740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    parameterized_test_registry_.RegisterTests();
37750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    parameterized_tests_registered_ = true;
37760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
37770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#endif
37780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
37790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
37800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}  // namespace internal
37810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
37820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Creates the test object, runs it, records its result, and then
37830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// deletes it.
37840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid TestInfo::Run() {
37850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (!should_run_) return;
37860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
37870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Tells UnitTest where to store test result.
37880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  internal::UnitTestImpl* const impl = internal::GetUnitTestImpl();
37890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  impl->set_current_test_info(this);
37900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
37910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater();
37920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
37930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Notifies the unit test event listeners that a test is about to start.
37940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  repeater->OnTestStart(*this);
37950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
37960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const TimeInMillis start = internal::GetTimeInMillis();
37970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
37980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  impl->os_stack_trace_getter()->UponLeavingGTest();
37990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
38000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Creates the test object.
38010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  Test* const test = internal::HandleExceptionsInMethodIfSupported(
38020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      factory_, &internal::TestFactoryBase::CreateTest,
38030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      "the test fixture's constructor");
38040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
38050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Runs the test only if the test object was created and its
38060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // constructor didn't generate a fatal failure.
38070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if ((test != NULL) && !Test::HasFatalFailure()) {
38080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // This doesn't throw as all user code that can throw are wrapped into
38090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // exception handling code.
38100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    test->Run();
38110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
38120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
38130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Deletes the test object.
38140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  impl->os_stack_trace_getter()->UponLeavingGTest();
38150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  internal::HandleExceptionsInMethodIfSupported(
38160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      test, &Test::DeleteSelf_, "the test fixture's destructor");
38170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
38180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  result_.set_elapsed_time(internal::GetTimeInMillis() - start);
38190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
38200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Notifies the unit test event listener that a test has just finished.
38210d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  repeater->OnTestEnd(*this);
38220d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
38230d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Tells UnitTest to stop associating assertion results to this
38240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // test.
38250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  impl->set_current_test_info(NULL);
38260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
38270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
38280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// class TestCase
38290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
38300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Gets the number of successful tests in this test case.
38310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgint TestCase::successful_test_count() const {
38320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return CountIf(test_info_list_, TestPassed);
38330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
38340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
38350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Gets the number of failed tests in this test case.
38360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgint TestCase::failed_test_count() const {
38370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return CountIf(test_info_list_, TestFailed);
38380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
38390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
38400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Gets the number of disabled tests that will be reported in the XML report.
38410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgint TestCase::reportable_disabled_test_count() const {
38420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return CountIf(test_info_list_, TestReportableDisabled);
38430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
38440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
38450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Gets the number of disabled tests in this test case.
38460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgint TestCase::disabled_test_count() const {
38470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return CountIf(test_info_list_, TestDisabled);
38480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
38490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
38500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Gets the number of tests to be printed in the XML report.
38510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgint TestCase::reportable_test_count() const {
38520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return CountIf(test_info_list_, TestReportable);
38530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
38540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
38550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Get the number of tests in this test case that should run.
38560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgint TestCase::test_to_run_count() const {
38570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return CountIf(test_info_list_, ShouldRunTest);
38580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
38590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
38600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Gets the number of all tests.
38610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgint TestCase::total_test_count() const {
38620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return static_cast<int>(test_info_list_.size());
38630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
38640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
38650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Creates a TestCase with the given name.
38660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
38670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Arguments:
38680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
38690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//   name:         name of the test case
38700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//   a_type_param: the name of the test case's type parameter, or NULL if
38710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//                 this is not a typed or a type-parameterized test case.
38720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//   set_up_tc:    pointer to the function that sets up the test case
38730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//   tear_down_tc: pointer to the function that tears down the test case
38740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgTestCase::TestCase(const char* a_name, const char* a_type_param,
38750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                   Test::SetUpTestCaseFunc set_up_tc,
38760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                   Test::TearDownTestCaseFunc tear_down_tc)
38770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    : name_(a_name),
38780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      type_param_(a_type_param ? new std::string(a_type_param) : NULL),
38790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      set_up_tc_(set_up_tc),
38800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      tear_down_tc_(tear_down_tc),
38810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      should_run_(false),
38820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      elapsed_time_(0) {
38830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
38840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
38850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Destructor of TestCase.
38860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgTestCase::~TestCase() {
38870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Deletes every Test in the collection.
38880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  ForEach(test_info_list_, internal::Delete<TestInfo>);
38890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
38900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
38910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Returns the i-th test among all the tests. i can range from 0 to
38920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// total_test_count() - 1. If i is not in that range, returns NULL.
38930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgconst TestInfo* TestCase::GetTestInfo(int i) const {
38940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const int index = GetElementOr(test_indices_, i, -1);
38950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return index < 0 ? NULL : test_info_list_[index];
38960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
38970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
38980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Returns the i-th test among all the tests. i can range from 0 to
38990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// total_test_count() - 1. If i is not in that range, returns NULL.
39000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgTestInfo* TestCase::GetMutableTestInfo(int i) {
39010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const int index = GetElementOr(test_indices_, i, -1);
39020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return index < 0 ? NULL : test_info_list_[index];
39030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
39040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
39050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Adds a test to this test case.  Will delete the test upon
39060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// destruction of the TestCase object.
39070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid TestCase::AddTestInfo(TestInfo * test_info) {
39080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  test_info_list_.push_back(test_info);
39090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  test_indices_.push_back(static_cast<int>(test_indices_.size()));
39100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
39110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
39120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Runs every test in this TestCase.
39130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid TestCase::Run() {
39140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (!should_run_) return;
39150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
39160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  internal::UnitTestImpl* const impl = internal::GetUnitTestImpl();
39170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  impl->set_current_test_case(this);
39180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
39190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater();
39200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
39210d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  repeater->OnTestCaseStart(*this);
39220d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  impl->os_stack_trace_getter()->UponLeavingGTest();
39230d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  internal::HandleExceptionsInMethodIfSupported(
39240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      this, &TestCase::RunSetUpTestCase, "SetUpTestCase()");
39250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
39260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const internal::TimeInMillis start = internal::GetTimeInMillis();
39270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  for (int i = 0; i < total_test_count(); i++) {
39280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    GetMutableTestInfo(i)->Run();
39290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
39300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  elapsed_time_ = internal::GetTimeInMillis() - start;
39310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
39320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  impl->os_stack_trace_getter()->UponLeavingGTest();
39330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  internal::HandleExceptionsInMethodIfSupported(
39340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      this, &TestCase::RunTearDownTestCase, "TearDownTestCase()");
39350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
39360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  repeater->OnTestCaseEnd(*this);
39370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  impl->set_current_test_case(NULL);
39380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
39390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
39400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Clears the results of all tests in this test case.
39410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid TestCase::ClearResult() {
39420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  ad_hoc_test_result_.Clear();
39430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  ForEach(test_info_list_, TestInfo::ClearTestResult);
39440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
39450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
39460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Shuffles the tests in this test case.
39470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid TestCase::ShuffleTests(internal::Random* random) {
39480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  Shuffle(random, &test_indices_);
39490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
39500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
39510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Restores the test order to before the first shuffle.
39520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid TestCase::UnshuffleTests() {
39530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  for (size_t i = 0; i < test_indices_.size(); i++) {
39540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    test_indices_[i] = static_cast<int>(i);
39550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
39560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
39570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
39580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Formats a countable noun.  Depending on its quantity, either the
39590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// singular form or the plural form is used. e.g.
39600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
39610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// FormatCountableNoun(1, "formula", "formuli") returns "1 formula".
39620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// FormatCountableNoun(5, "book", "books") returns "5 books".
39630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstatic std::string FormatCountableNoun(int count,
39640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                       const char * singular_form,
39650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                       const char * plural_form) {
39660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return internal::StreamableToString(count) + " " +
39670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      (count == 1 ? singular_form : plural_form);
39680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
39690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
39700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Formats the count of tests.
39710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstatic std::string FormatTestCount(int test_count) {
39720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return FormatCountableNoun(test_count, "test", "tests");
39730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
39740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
39750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Formats the count of test cases.
39760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstatic std::string FormatTestCaseCount(int test_case_count) {
39770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return FormatCountableNoun(test_case_count, "test case", "test cases");
39780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
39790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
39800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Converts a TestPartResult::Type enum to human-friendly string
39810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// representation.  Both kNonFatalFailure and kFatalFailure are translated
39820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// to "Failure", as the user usually doesn't care about the difference
39830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// between the two when viewing the test result.
39840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstatic const char * TestPartResultTypeToString(TestPartResult::Type type) {
39850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  switch (type) {
39860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    case TestPartResult::kSuccess:
39870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      return "Success";
39880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
39890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    case TestPartResult::kNonFatalFailure:
39900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    case TestPartResult::kFatalFailure:
39910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#ifdef _MSC_VER
39920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      return "error: ";
39930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#else
39940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      return "Failure\n";
39950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#endif
39960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    default:
39970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      return "Unknown result type";
39980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
39990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
40000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
40010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgnamespace internal {
40020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
40030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Prints a TestPartResult to an std::string.
40040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstatic std::string PrintTestPartResultToString(
40050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const TestPartResult& test_part_result) {
40060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return (Message()
40070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          << internal::FormatFileLocation(test_part_result.file_name(),
40080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                          test_part_result.line_number())
40090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          << " " << TestPartResultTypeToString(test_part_result.type())
40100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          << test_part_result.message()).GetString();
40110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
40120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
40130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Prints a TestPartResult.
40140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstatic void PrintTestPartResult(const TestPartResult& test_part_result) {
40150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const std::string& result =
40160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      PrintTestPartResultToString(test_part_result);
40170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  printf("%s\n", result.c_str());
40180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  fflush(stdout);
40190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // If the test program runs in Visual Studio or a debugger, the
40200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // following statements add the test part result message to the Output
40210d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // window such that the user can double-click on it to jump to the
40220d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // corresponding source code location; otherwise they do nothing.
40230d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE
40240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // We don't call OutputDebugString*() on Windows Mobile, as printing
40250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // to stdout is done by OutputDebugString() there already - we don't
40260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // want the same message printed twice.
40270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  ::OutputDebugStringA(result.c_str());
40280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  ::OutputDebugStringA("\n");
40290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#endif
40300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
40310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
40320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// class PrettyUnitTestResultPrinter
40330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
40340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgenum GTestColor {
40350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  COLOR_DEFAULT,
40360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  COLOR_RED,
40370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  COLOR_GREEN,
40380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  COLOR_YELLOW
40390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org};
40400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
40410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE
40420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
40430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Returns the character attribute for the given color.
40440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgWORD GetColorAttribute(GTestColor color) {
40450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  switch (color) {
40460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    case COLOR_RED:    return FOREGROUND_RED;
40470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    case COLOR_GREEN:  return FOREGROUND_GREEN;
40480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    case COLOR_YELLOW: return FOREGROUND_RED | FOREGROUND_GREEN;
40490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    default:           return 0;
40500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
40510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
40520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
40530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#else
40540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
40550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Returns the ANSI color code for the given color.  COLOR_DEFAULT is
40560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// an invalid input.
40570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgconst char* GetAnsiColorCode(GTestColor color) {
40580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  switch (color) {
40590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    case COLOR_RED:     return "1";
40600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    case COLOR_GREEN:   return "2";
40610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    case COLOR_YELLOW:  return "3";
40620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    default:            return NULL;
40630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  };
40640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
40650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
40660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#endif  // GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE
40670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
40680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Returns true iff Google Test should use colors in the output.
40690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgbool ShouldUseColor(bool stdout_is_tty) {
40700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const char* const gtest_color = GTEST_FLAG(color).c_str();
40710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
40720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (String::CaseInsensitiveCStringEquals(gtest_color, "auto")) {
40730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#if GTEST_OS_WINDOWS
40740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // On Windows the TERM variable is usually not set, but the
40750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // console there does support colors.
40760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return stdout_is_tty;
40770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#else
40780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // On non-Windows platforms, we rely on the TERM variable.
40790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const char* const term = posix::GetEnv("TERM");
40800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const bool term_supports_color =
40810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        String::CStringEquals(term, "xterm") ||
40820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        String::CStringEquals(term, "xterm-color") ||
40830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        String::CStringEquals(term, "xterm-256color") ||
40840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        String::CStringEquals(term, "screen") ||
40850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        String::CStringEquals(term, "screen-256color") ||
40860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        String::CStringEquals(term, "linux") ||
40870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        String::CStringEquals(term, "cygwin");
40880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return stdout_is_tty && term_supports_color;
40890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#endif  // GTEST_OS_WINDOWS
40900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
40910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
40920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return String::CaseInsensitiveCStringEquals(gtest_color, "yes") ||
40930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      String::CaseInsensitiveCStringEquals(gtest_color, "true") ||
40940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      String::CaseInsensitiveCStringEquals(gtest_color, "t") ||
40950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      String::CStringEquals(gtest_color, "1");
40960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // We take "yes", "true", "t", and "1" as meaning "yes".  If the
40970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // value is neither one of these nor "auto", we treat it as "no" to
40980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // be conservative.
40990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
41000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
41010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Helpers for printing colored strings to stdout. Note that on Windows, we
41020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// cannot simply emit special characters and have the terminal change colors.
41030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// This routine must actually emit the characters rather than return a string
41040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// that would be colored when printed, as can be done on Linux.
41050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid ColoredPrintf(GTestColor color, const char* fmt, ...) {
41060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  va_list args;
41070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  va_start(args, fmt);
41080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
41090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_SYMBIAN || GTEST_OS_ZOS || GTEST_OS_IOS
41100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const bool use_color = false;
41110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#else
41120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  static const bool in_color_mode =
41130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      ShouldUseColor(posix::IsATTY(posix::FileNo(stdout)) != 0);
41140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const bool use_color = in_color_mode && (color != COLOR_DEFAULT);
41150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#endif  // GTEST_OS_WINDOWS_MOBILE || GTEST_OS_SYMBIAN || GTEST_OS_ZOS
41160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // The '!= 0' comparison is necessary to satisfy MSVC 7.1.
41170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
41180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (!use_color) {
41190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    vprintf(fmt, args);
41200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    va_end(args);
41210d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return;
41220d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
41230d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
41240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE
41250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const HANDLE stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE);
41260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
41270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Gets the current text color.
41280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  CONSOLE_SCREEN_BUFFER_INFO buffer_info;
41290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  GetConsoleScreenBufferInfo(stdout_handle, &buffer_info);
41300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const WORD old_color_attrs = buffer_info.wAttributes;
41310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
41320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // We need to flush the stream buffers into the console before each
41330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // SetConsoleTextAttribute call lest it affect the text that is already
41340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // printed but has not yet reached the console.
41350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  fflush(stdout);
41360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  SetConsoleTextAttribute(stdout_handle,
41370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                          GetColorAttribute(color) | FOREGROUND_INTENSITY);
41380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  vprintf(fmt, args);
41390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
41400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  fflush(stdout);
41410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Restores the text color.
41420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  SetConsoleTextAttribute(stdout_handle, old_color_attrs);
41430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#else
41440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  printf("\033[0;3%sm", GetAnsiColorCode(color));
41450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  vprintf(fmt, args);
41460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  printf("\033[m");  // Resets the terminal to default.
41470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#endif  // GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE
41480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  va_end(args);
41490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
41500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
41510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Text printed in Google Test's text output and --gunit_list_tests
41520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// output to label the type parameter and value parameter for a test.
41530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstatic const char kTypeParamLabel[] = "TypeParam";
41540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstatic const char kValueParamLabel[] = "GetParam()";
41550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
41560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid PrintFullTestCommentIfPresent(const TestInfo& test_info) {
41570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const char* const type_param = test_info.type_param();
41580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const char* const value_param = test_info.value_param();
41590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
41600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (type_param != NULL || value_param != NULL) {
41610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    printf(", where ");
41620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    if (type_param != NULL) {
41630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      printf("%s = %s", kTypeParamLabel, type_param);
41640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      if (value_param != NULL)
41650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        printf(" and ");
41660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    }
41670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    if (value_param != NULL) {
41680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      printf("%s = %s", kValueParamLabel, value_param);
41690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    }
41700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
41710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
41720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
41730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// This class implements the TestEventListener interface.
41740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
41750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Class PrettyUnitTestResultPrinter is copyable.
41760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgclass PrettyUnitTestResultPrinter : public TestEventListener {
41770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org public:
41780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  PrettyUnitTestResultPrinter() {}
41790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  static void PrintTestName(const char * test_case, const char * test) {
41800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    printf("%s.%s", test_case, test);
41810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
41820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
41830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // The following methods override what's in the TestEventListener class.
41840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) {}
41850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  virtual void OnTestIterationStart(const UnitTest& unit_test, int iteration);
41860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  virtual void OnEnvironmentsSetUpStart(const UnitTest& unit_test);
41870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  virtual void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) {}
41880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  virtual void OnTestCaseStart(const TestCase& test_case);
41890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  virtual void OnTestStart(const TestInfo& test_info);
41900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  virtual void OnTestPartResult(const TestPartResult& result);
41910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  virtual void OnTestEnd(const TestInfo& test_info);
41920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  virtual void OnTestCaseEnd(const TestCase& test_case);
41930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test);
41940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  virtual void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) {}
41950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration);
41960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  virtual void OnTestProgramEnd(const UnitTest& /*unit_test*/) {}
41970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
41980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org private:
41990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  static void PrintFailedTests(const UnitTest& unit_test);
42000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org};
42010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
42020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Fired before each iteration of tests starts.
42030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid PrettyUnitTestResultPrinter::OnTestIterationStart(
42040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const UnitTest& unit_test, int iteration) {
42050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (GTEST_FLAG(repeat) != 1)
42060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    printf("\nRepeating all tests (iteration %d) . . .\n\n", iteration + 1);
42070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
42080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const char* const filter = GTEST_FLAG(filter).c_str();
42090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
42100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Prints the filter if it's not *.  This reminds the user that some
42110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // tests may be skipped.
42120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (!String::CStringEquals(filter, kUniversalFilter)) {
42130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    ColoredPrintf(COLOR_YELLOW,
42140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                  "Note: %s filter = %s\n", GTEST_NAME_, filter);
42150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
42160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
42170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (internal::ShouldShard(kTestTotalShards, kTestShardIndex, false)) {
42180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const Int32 shard_index = Int32FromEnvOrDie(kTestShardIndex, -1);
42190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    ColoredPrintf(COLOR_YELLOW,
42200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                  "Note: This is test shard %d of %s.\n",
42210d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                  static_cast<int>(shard_index) + 1,
42220d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                  internal::posix::GetEnv(kTestTotalShards));
42230d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
42240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
42250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (GTEST_FLAG(shuffle)) {
42260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    ColoredPrintf(COLOR_YELLOW,
42270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                  "Note: Randomizing tests' orders with a seed of %d .\n",
42280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                  unit_test.random_seed());
42290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
42300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
42310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  ColoredPrintf(COLOR_GREEN,  "[==========] ");
42320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  printf("Running %s from %s.\n",
42330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org         FormatTestCount(unit_test.test_to_run_count()).c_str(),
42340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org         FormatTestCaseCount(unit_test.test_case_to_run_count()).c_str());
42350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  fflush(stdout);
42360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
42370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
42380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid PrettyUnitTestResultPrinter::OnEnvironmentsSetUpStart(
42390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const UnitTest& /*unit_test*/) {
42400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  ColoredPrintf(COLOR_GREEN,  "[----------] ");
42410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  printf("Global test environment set-up.\n");
42420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  fflush(stdout);
42430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
42440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
42450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid PrettyUnitTestResultPrinter::OnTestCaseStart(const TestCase& test_case) {
42460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const std::string counts =
42470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      FormatCountableNoun(test_case.test_to_run_count(), "test", "tests");
42480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  ColoredPrintf(COLOR_GREEN, "[----------] ");
42490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  printf("%s from %s", counts.c_str(), test_case.name());
42500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (test_case.type_param() == NULL) {
42510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    printf("\n");
42520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  } else {
42530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    printf(", where %s = %s\n", kTypeParamLabel, test_case.type_param());
42540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
42550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  fflush(stdout);
42560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
42570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
42580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid PrettyUnitTestResultPrinter::OnTestStart(const TestInfo& test_info) {
42590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  ColoredPrintf(COLOR_GREEN,  "[ RUN      ] ");
42600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  PrintTestName(test_info.test_case_name(), test_info.name());
42610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  printf("\n");
42620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  fflush(stdout);
42630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
42640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
42650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Called after an assertion failure.
42660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid PrettyUnitTestResultPrinter::OnTestPartResult(
42670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const TestPartResult& result) {
42680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // If the test part succeeded, we don't need to do anything.
42690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (result.type() == TestPartResult::kSuccess)
42700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return;
42710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
42720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Print failure message from the assertion (e.g. expected this and got that).
42730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  PrintTestPartResult(result);
42740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  fflush(stdout);
42750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
42760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
42770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid PrettyUnitTestResultPrinter::OnTestEnd(const TestInfo& test_info) {
42780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (test_info.result()->Passed()) {
42790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    ColoredPrintf(COLOR_GREEN, "[       OK ] ");
42800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  } else {
42810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    ColoredPrintf(COLOR_RED, "[  FAILED  ] ");
42820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
42830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  PrintTestName(test_info.test_case_name(), test_info.name());
42840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (test_info.result()->Failed())
42850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    PrintFullTestCommentIfPresent(test_info);
42860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
42870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (GTEST_FLAG(print_time)) {
42880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    printf(" (%s ms)\n", internal::StreamableToString(
42890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org           test_info.result()->elapsed_time()).c_str());
42900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  } else {
42910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    printf("\n");
42920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
42930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  fflush(stdout);
42940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
42950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
42960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid PrettyUnitTestResultPrinter::OnTestCaseEnd(const TestCase& test_case) {
42970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (!GTEST_FLAG(print_time)) return;
42980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
42990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const std::string counts =
43000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      FormatCountableNoun(test_case.test_to_run_count(), "test", "tests");
43010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  ColoredPrintf(COLOR_GREEN, "[----------] ");
43020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  printf("%s from %s (%s ms total)\n\n",
43030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org         counts.c_str(), test_case.name(),
43040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org         internal::StreamableToString(test_case.elapsed_time()).c_str());
43050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  fflush(stdout);
43060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
43070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
43080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid PrettyUnitTestResultPrinter::OnEnvironmentsTearDownStart(
43090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const UnitTest& /*unit_test*/) {
43100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  ColoredPrintf(COLOR_GREEN,  "[----------] ");
43110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  printf("Global test environment tear-down\n");
43120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  fflush(stdout);
43130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
43140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
43150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Internal helper for printing the list of failed tests.
43160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid PrettyUnitTestResultPrinter::PrintFailedTests(const UnitTest& unit_test) {
43170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const int failed_test_count = unit_test.failed_test_count();
43180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (failed_test_count == 0) {
43190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return;
43200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
43210d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
43220d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  for (int i = 0; i < unit_test.total_test_case_count(); ++i) {
43230d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const TestCase& test_case = *unit_test.GetTestCase(i);
43240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    if (!test_case.should_run() || (test_case.failed_test_count() == 0)) {
43250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      continue;
43260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    }
43270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    for (int j = 0; j < test_case.total_test_count(); ++j) {
43280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      const TestInfo& test_info = *test_case.GetTestInfo(j);
43290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      if (!test_info.should_run() || test_info.result()->Passed()) {
43300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        continue;
43310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      }
43320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      ColoredPrintf(COLOR_RED, "[  FAILED  ] ");
43330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      printf("%s.%s", test_case.name(), test_info.name());
43340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      PrintFullTestCommentIfPresent(test_info);
43350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      printf("\n");
43360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    }
43370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
43380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
43390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
43400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid PrettyUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test,
43410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                                     int /*iteration*/) {
43420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  ColoredPrintf(COLOR_GREEN,  "[==========] ");
43430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  printf("%s from %s ran.",
43440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org         FormatTestCount(unit_test.test_to_run_count()).c_str(),
43450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org         FormatTestCaseCount(unit_test.test_case_to_run_count()).c_str());
43460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (GTEST_FLAG(print_time)) {
43470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    printf(" (%s ms total)",
43480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org           internal::StreamableToString(unit_test.elapsed_time()).c_str());
43490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
43500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  printf("\n");
43510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  ColoredPrintf(COLOR_GREEN,  "[  PASSED  ] ");
43520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  printf("%s.\n", FormatTestCount(unit_test.successful_test_count()).c_str());
43530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
43540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  int num_failures = unit_test.failed_test_count();
43550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (!unit_test.Passed()) {
43560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const int failed_test_count = unit_test.failed_test_count();
43570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    ColoredPrintf(COLOR_RED,  "[  FAILED  ] ");
43580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    printf("%s, listed below:\n", FormatTestCount(failed_test_count).c_str());
43590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    PrintFailedTests(unit_test);
43600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    printf("\n%2d FAILED %s\n", num_failures,
43610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                        num_failures == 1 ? "TEST" : "TESTS");
43620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
43630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
43640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  int num_disabled = unit_test.reportable_disabled_test_count();
43650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (num_disabled && !GTEST_FLAG(also_run_disabled_tests)) {
43660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    if (!num_failures) {
43670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      printf("\n");  // Add a spacer if no FAILURE banner is displayed.
43680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    }
43690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    ColoredPrintf(COLOR_YELLOW,
43700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                  "  YOU HAVE %d DISABLED %s\n\n",
43710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                  num_disabled,
43720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                  num_disabled == 1 ? "TEST" : "TESTS");
43730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
43740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Ensure that Google Test output is printed before, e.g., heapchecker output.
43750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  fflush(stdout);
43760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
43770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
43780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// End PrettyUnitTestResultPrinter
43790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
43800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// class TestEventRepeater
43810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
43820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// This class forwards events to other event listeners.
43830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgclass TestEventRepeater : public TestEventListener {
43840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org public:
43850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  TestEventRepeater() : forwarding_enabled_(true) {}
43860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  virtual ~TestEventRepeater();
43870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  void Append(TestEventListener *listener);
43880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  TestEventListener* Release(TestEventListener* listener);
43890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
43900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Controls whether events will be forwarded to listeners_. Set to false
43910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // in death test child processes.
43920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  bool forwarding_enabled() const { return forwarding_enabled_; }
43930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  void set_forwarding_enabled(bool enable) { forwarding_enabled_ = enable; }
43940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
43950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  virtual void OnTestProgramStart(const UnitTest& unit_test);
43960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  virtual void OnTestIterationStart(const UnitTest& unit_test, int iteration);
43970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  virtual void OnEnvironmentsSetUpStart(const UnitTest& unit_test);
43980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  virtual void OnEnvironmentsSetUpEnd(const UnitTest& unit_test);
43990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  virtual void OnTestCaseStart(const TestCase& test_case);
44000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  virtual void OnTestStart(const TestInfo& test_info);
44010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  virtual void OnTestPartResult(const TestPartResult& result);
44020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  virtual void OnTestEnd(const TestInfo& test_info);
44030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  virtual void OnTestCaseEnd(const TestCase& test_case);
44040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test);
44050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  virtual void OnEnvironmentsTearDownEnd(const UnitTest& unit_test);
44060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration);
44070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  virtual void OnTestProgramEnd(const UnitTest& unit_test);
44080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
44090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org private:
44100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Controls whether events will be forwarded to listeners_. Set to false
44110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // in death test child processes.
44120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  bool forwarding_enabled_;
44130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // The list of listeners that receive events.
44140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  std::vector<TestEventListener*> listeners_;
44150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
44160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  GTEST_DISALLOW_COPY_AND_ASSIGN_(TestEventRepeater);
44170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org};
44180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
44190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgTestEventRepeater::~TestEventRepeater() {
44200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  ForEach(listeners_, Delete<TestEventListener>);
44210d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
44220d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
44230d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid TestEventRepeater::Append(TestEventListener *listener) {
44240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  listeners_.push_back(listener);
44250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
44260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
44270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// TODO(vladl@google.com): Factor the search functionality into Vector::Find.
44280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgTestEventListener* TestEventRepeater::Release(TestEventListener *listener) {
44290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  for (size_t i = 0; i < listeners_.size(); ++i) {
44300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    if (listeners_[i] == listener) {
44310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      listeners_.erase(listeners_.begin() + i);
44320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      return listener;
44330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    }
44340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
44350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
44360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return NULL;
44370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
44380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
44390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Since most methods are very similar, use macros to reduce boilerplate.
44400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// This defines a member that forwards the call to all listeners.
44410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#define GTEST_REPEATER_METHOD_(Name, Type) \
44420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid TestEventRepeater::Name(const Type& parameter) { \
44430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (forwarding_enabled_) { \
44440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    for (size_t i = 0; i < listeners_.size(); i++) { \
44450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      listeners_[i]->Name(parameter); \
44460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    } \
44470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  } \
44480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
44490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// This defines a member that forwards the call to all listeners in reverse
44500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// order.
44510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#define GTEST_REVERSE_REPEATER_METHOD_(Name, Type) \
44520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid TestEventRepeater::Name(const Type& parameter) { \
44530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (forwarding_enabled_) { \
44540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    for (int i = static_cast<int>(listeners_.size()) - 1; i >= 0; i--) { \
44550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      listeners_[i]->Name(parameter); \
44560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    } \
44570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  } \
44580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
44590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
44600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgGTEST_REPEATER_METHOD_(OnTestProgramStart, UnitTest)
44610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgGTEST_REPEATER_METHOD_(OnEnvironmentsSetUpStart, UnitTest)
44620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgGTEST_REPEATER_METHOD_(OnTestCaseStart, TestCase)
44630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgGTEST_REPEATER_METHOD_(OnTestStart, TestInfo)
44640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgGTEST_REPEATER_METHOD_(OnTestPartResult, TestPartResult)
44650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgGTEST_REPEATER_METHOD_(OnEnvironmentsTearDownStart, UnitTest)
44660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgGTEST_REVERSE_REPEATER_METHOD_(OnEnvironmentsSetUpEnd, UnitTest)
44670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgGTEST_REVERSE_REPEATER_METHOD_(OnEnvironmentsTearDownEnd, UnitTest)
44680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgGTEST_REVERSE_REPEATER_METHOD_(OnTestEnd, TestInfo)
44690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgGTEST_REVERSE_REPEATER_METHOD_(OnTestCaseEnd, TestCase)
44700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgGTEST_REVERSE_REPEATER_METHOD_(OnTestProgramEnd, UnitTest)
44710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
44720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#undef GTEST_REPEATER_METHOD_
44730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#undef GTEST_REVERSE_REPEATER_METHOD_
44740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
44750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid TestEventRepeater::OnTestIterationStart(const UnitTest& unit_test,
44760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                             int iteration) {
44770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (forwarding_enabled_) {
44780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    for (size_t i = 0; i < listeners_.size(); i++) {
44790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      listeners_[i]->OnTestIterationStart(unit_test, iteration);
44800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    }
44810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
44820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
44830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
44840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid TestEventRepeater::OnTestIterationEnd(const UnitTest& unit_test,
44850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                           int iteration) {
44860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (forwarding_enabled_) {
44870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    for (int i = static_cast<int>(listeners_.size()) - 1; i >= 0; i--) {
44880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      listeners_[i]->OnTestIterationEnd(unit_test, iteration);
44890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    }
44900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
44910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
44920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
44930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// End TestEventRepeater
44940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
44950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// This class generates an XML output file.
44960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgclass XmlUnitTestResultPrinter : public EmptyTestEventListener {
44970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org public:
44980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  explicit XmlUnitTestResultPrinter(const char* output_file);
44990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
45000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration);
45010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
45020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org private:
45030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Is c a whitespace character that is normalized to a space character
45040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // when it appears in an XML attribute value?
45050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  static bool IsNormalizableWhitespace(char c) {
45060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return c == 0x9 || c == 0xA || c == 0xD;
45070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
45080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
45090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // May c appear in a well-formed XML document?
45100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  static bool IsValidXmlCharacter(char c) {
45110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return IsNormalizableWhitespace(c) || c >= 0x20;
45120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
45130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
45140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Returns an XML-escaped copy of the input string str.  If
45150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // is_attribute is true, the text is meant to appear as an attribute
45160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // value, and normalizable whitespace is preserved by replacing it
45170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // with character references.
45180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  static std::string EscapeXml(const std::string& str, bool is_attribute);
45190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
45200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Returns the given string with all characters invalid in XML removed.
45210d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  static std::string RemoveInvalidXmlCharacters(const std::string& str);
45220d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
45230d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Convenience wrapper around EscapeXml when str is an attribute value.
45240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  static std::string EscapeXmlAttribute(const std::string& str) {
45250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return EscapeXml(str, true);
45260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
45270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
45280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Convenience wrapper around EscapeXml when str is not an attribute value.
45290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  static std::string EscapeXmlText(const char* str) {
45300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return EscapeXml(str, false);
45310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
45320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
45330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Verifies that the given attribute belongs to the given element and
45340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // streams the attribute as XML.
45350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  static void OutputXmlAttribute(std::ostream* stream,
45360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                 const std::string& element_name,
45370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                 const std::string& name,
45380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                 const std::string& value);
45390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
45400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Streams an XML CDATA section, escaping invalid CDATA sequences as needed.
45410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  static void OutputXmlCDataSection(::std::ostream* stream, const char* data);
45420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
45430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Streams an XML representation of a TestInfo object.
45440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  static void OutputXmlTestInfo(::std::ostream* stream,
45450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                const char* test_case_name,
45460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                const TestInfo& test_info);
45470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
45480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Prints an XML representation of a TestCase object
45490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  static void PrintXmlTestCase(::std::ostream* stream,
45500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                               const TestCase& test_case);
45510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
45520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Prints an XML summary of unit_test to output stream out.
45530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  static void PrintXmlUnitTest(::std::ostream* stream,
45540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                               const UnitTest& unit_test);
45550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
45560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Produces a string representing the test properties in a result as space
45570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // delimited XML attributes based on the property key="value" pairs.
45580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // When the std::string is not empty, it includes a space at the beginning,
45590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // to delimit this attribute from prior attributes.
45600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  static std::string TestPropertiesAsXmlAttributes(const TestResult& result);
45610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
45620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // The output file.
45630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const std::string output_file_;
45640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
45650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  GTEST_DISALLOW_COPY_AND_ASSIGN_(XmlUnitTestResultPrinter);
45660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org};
45670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
45680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Creates a new XmlUnitTestResultPrinter.
45690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgXmlUnitTestResultPrinter::XmlUnitTestResultPrinter(const char* output_file)
45700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    : output_file_(output_file) {
45710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (output_file_.c_str() == NULL || output_file_.empty()) {
45720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    fprintf(stderr, "XML output file may not be null\n");
45730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    fflush(stderr);
45740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    exit(EXIT_FAILURE);
45750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
45760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
45770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
45780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Called after the unit test ends.
45790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid XmlUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test,
45800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                                  int /*iteration*/) {
45810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  FILE* xmlout = NULL;
45820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  FilePath output_file(output_file_);
45830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  FilePath output_dir(output_file.RemoveFileName());
45840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
45850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (output_dir.CreateDirectoriesRecursively()) {
45860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    xmlout = posix::FOpen(output_file_.c_str(), "w");
45870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
45880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (xmlout == NULL) {
45890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // TODO(wan): report the reason of the failure.
45900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    //
45910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // We don't do it for now as:
45920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    //
45930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    //   1. There is no urgent need for it.
45940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    //   2. It's a bit involved to make the errno variable thread-safe on
45950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    //      all three operating systems (Linux, Windows, and Mac OS).
45960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    //   3. To interpret the meaning of errno in a thread-safe way,
45970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    //      we need the strerror_r() function, which is not available on
45980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    //      Windows.
45990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    fprintf(stderr,
46000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org            "Unable to open file \"%s\"\n",
46010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org            output_file_.c_str());
46020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    fflush(stderr);
46030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    exit(EXIT_FAILURE);
46040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
46050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  std::stringstream stream;
46060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  PrintXmlUnitTest(&stream, unit_test);
46070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  fprintf(xmlout, "%s", StringStreamToString(&stream).c_str());
46080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  fclose(xmlout);
46090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
46100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
46110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Returns an XML-escaped copy of the input string str.  If is_attribute
46120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// is true, the text is meant to appear as an attribute value, and
46130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// normalizable whitespace is preserved by replacing it with character
46140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// references.
46150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
46160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Invalid XML characters in str, if any, are stripped from the output.
46170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// It is expected that most, if not all, of the text processed by this
46180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// module will consist of ordinary English text.
46190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// If this module is ever modified to produce version 1.1 XML output,
46200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// most invalid characters can be retained using character references.
46210d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// TODO(wan): It might be nice to have a minimally invasive, human-readable
46220d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// escaping scheme for invalid characters, rather than dropping them.
46230d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstd::string XmlUnitTestResultPrinter::EscapeXml(
46240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const std::string& str, bool is_attribute) {
46250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  Message m;
46260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
46270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  for (size_t i = 0; i < str.size(); ++i) {
46280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const char ch = str[i];
46290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    switch (ch) {
46300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      case '<':
46310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        m << "&lt;";
46320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        break;
46330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      case '>':
46340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        m << "&gt;";
46350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        break;
46360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      case '&':
46370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        m << "&amp;";
46380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        break;
46390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      case '\'':
46400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        if (is_attribute)
46410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          m << "&apos;";
46420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        else
46430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          m << '\'';
46440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        break;
46450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      case '"':
46460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        if (is_attribute)
46470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          m << "&quot;";
46480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        else
46490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          m << '"';
46500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        break;
46510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      default:
46520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        if (IsValidXmlCharacter(ch)) {
46530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          if (is_attribute && IsNormalizableWhitespace(ch))
46540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org            m << "&#x" << String::FormatByte(static_cast<unsigned char>(ch))
46550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org              << ";";
46560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          else
46570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org            m << ch;
46580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        }
46590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        break;
46600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    }
46610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
46620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
46630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return m.GetString();
46640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
46650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
46660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Returns the given string with all characters invalid in XML removed.
46670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Currently invalid characters are dropped from the string. An
46680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// alternative is to replace them with certain characters such as . or ?.
46690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstd::string XmlUnitTestResultPrinter::RemoveInvalidXmlCharacters(
46700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const std::string& str) {
46710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  std::string output;
46720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  output.reserve(str.size());
46730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  for (std::string::const_iterator it = str.begin(); it != str.end(); ++it)
46740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    if (IsValidXmlCharacter(*it))
46750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      output.push_back(*it);
46760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
46770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return output;
46780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
46790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
46800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// The following routines generate an XML representation of a UnitTest
46810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// object.
46820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
46830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// This is how Google Test concepts map to the DTD:
46840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
46850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// <testsuites name="AllTests">        <-- corresponds to a UnitTest object
46860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//   <testsuite name="testcase-name">  <-- corresponds to a TestCase object
46870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//     <testcase name="test-name">     <-- corresponds to a TestInfo object
46880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//       <failure message="...">...</failure>
46890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//       <failure message="...">...</failure>
46900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//       <failure message="...">...</failure>
46910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//                                     <-- individual assertion failures
46920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//     </testcase>
46930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//   </testsuite>
46940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// </testsuites>
46950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
46960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Formats the given time in milliseconds as seconds.
46970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstd::string FormatTimeInMillisAsSeconds(TimeInMillis ms) {
46980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  ::std::stringstream ss;
46990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  ss << ms/1000.0;
47000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return ss.str();
47010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
47020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
47030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Converts the given epoch time in milliseconds to a date string in the ISO
47040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// 8601 format, without the timezone information.
47050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstd::string FormatEpochTimeInMillisAsIso8601(TimeInMillis ms) {
47060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Using non-reentrant version as localtime_r is not portable.
47070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  time_t seconds = static_cast<time_t>(ms / 1000);
47080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#ifdef _MSC_VER
47090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# pragma warning(push)          // Saves the current warning state.
47100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# pragma warning(disable:4996)  // Temporarily disables warning 4996
47110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                // (function or variable may be unsafe).
47120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const struct tm* const time_struct = localtime(&seconds);  // NOLINT
47130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# pragma warning(pop)           // Restores the warning state again.
47140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#else
47150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const struct tm* const time_struct = localtime(&seconds);  // NOLINT
47160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#endif
47170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (time_struct == NULL)
47180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return "";  // Invalid ms value
47190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
47200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // YYYY-MM-DDThh:mm:ss
47210d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return StreamableToString(time_struct->tm_year + 1900) + "-" +
47220d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      String::FormatIntWidth2(time_struct->tm_mon + 1) + "-" +
47230d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      String::FormatIntWidth2(time_struct->tm_mday) + "T" +
47240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      String::FormatIntWidth2(time_struct->tm_hour) + ":" +
47250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      String::FormatIntWidth2(time_struct->tm_min) + ":" +
47260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      String::FormatIntWidth2(time_struct->tm_sec);
47270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
47280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
47290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Streams an XML CDATA section, escaping invalid CDATA sequences as needed.
47300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid XmlUnitTestResultPrinter::OutputXmlCDataSection(::std::ostream* stream,
47310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                                     const char* data) {
47320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const char* segment = data;
47330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  *stream << "<![CDATA[";
47340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  for (;;) {
47350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const char* const next_segment = strstr(segment, "]]>");
47360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    if (next_segment != NULL) {
47370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      stream->write(
47380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          segment, static_cast<std::streamsize>(next_segment - segment));
47390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      *stream << "]]>]]&gt;<![CDATA[";
47400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      segment = next_segment + strlen("]]>");
47410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    } else {
47420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      *stream << segment;
47430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      break;
47440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    }
47450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
47460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  *stream << "]]>";
47470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
47480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
47490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid XmlUnitTestResultPrinter::OutputXmlAttribute(
47500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    std::ostream* stream,
47510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const std::string& element_name,
47520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const std::string& name,
47530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const std::string& value) {
47540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const std::vector<std::string>& allowed_names =
47550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      GetReservedAttributesForElement(element_name);
47560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
47570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  GTEST_CHECK_(std::find(allowed_names.begin(), allowed_names.end(), name) !=
47580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                   allowed_names.end())
47590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      << "Attribute " << name << " is not allowed for element <" << element_name
47600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      << ">.";
47610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
47620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  *stream << " " << name << "=\"" << EscapeXmlAttribute(value) << "\"";
47630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
47640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
47650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Prints an XML representation of a TestInfo object.
47660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// TODO(wan): There is also value in printing properties with the plain printer.
47670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid XmlUnitTestResultPrinter::OutputXmlTestInfo(::std::ostream* stream,
47680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                                 const char* test_case_name,
47690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                                 const TestInfo& test_info) {
47700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const TestResult& result = *test_info.result();
47710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const std::string kTestcase = "testcase";
47720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
47730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  *stream << "    <testcase";
47740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  OutputXmlAttribute(stream, kTestcase, "name", test_info.name());
47750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
47760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (test_info.value_param() != NULL) {
47770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    OutputXmlAttribute(stream, kTestcase, "value_param",
47780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                       test_info.value_param());
47790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
47800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (test_info.type_param() != NULL) {
47810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    OutputXmlAttribute(stream, kTestcase, "type_param", test_info.type_param());
47820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
47830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
47840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  OutputXmlAttribute(stream, kTestcase, "status",
47850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                     test_info.should_run() ? "run" : "notrun");
47860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  OutputXmlAttribute(stream, kTestcase, "time",
47870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                     FormatTimeInMillisAsSeconds(result.elapsed_time()));
47880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  OutputXmlAttribute(stream, kTestcase, "classname", test_case_name);
47890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  *stream << TestPropertiesAsXmlAttributes(result);
47900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
47910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  int failures = 0;
47920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  for (int i = 0; i < result.total_part_count(); ++i) {
47930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const TestPartResult& part = result.GetTestPartResult(i);
47940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    if (part.failed()) {
47950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      if (++failures == 1) {
47960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        *stream << ">\n";
47970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      }
47980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      const string location = internal::FormatCompilerIndependentFileLocation(
47990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          part.file_name(), part.line_number());
48000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      const string summary = location + "\n" + part.summary();
48010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      *stream << "      <failure message=\""
48020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org              << EscapeXmlAttribute(summary.c_str())
48030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org              << "\" type=\"\">";
48040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      const string detail = location + "\n" + part.message();
48050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      OutputXmlCDataSection(stream, RemoveInvalidXmlCharacters(detail).c_str());
48060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      *stream << "</failure>\n";
48070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    }
48080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
48090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
48100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (failures == 0)
48110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    *stream << " />\n";
48120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  else
48130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    *stream << "    </testcase>\n";
48140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
48150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
48160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Prints an XML representation of a TestCase object
48170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid XmlUnitTestResultPrinter::PrintXmlTestCase(std::ostream* stream,
48180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                                const TestCase& test_case) {
48190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const std::string kTestsuite = "testsuite";
48200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  *stream << "  <" << kTestsuite;
48210d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  OutputXmlAttribute(stream, kTestsuite, "name", test_case.name());
48220d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  OutputXmlAttribute(stream, kTestsuite, "tests",
48230d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                     StreamableToString(test_case.reportable_test_count()));
48240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  OutputXmlAttribute(stream, kTestsuite, "failures",
48250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                     StreamableToString(test_case.failed_test_count()));
48260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  OutputXmlAttribute(
48270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      stream, kTestsuite, "disabled",
48280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      StreamableToString(test_case.reportable_disabled_test_count()));
48290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  OutputXmlAttribute(stream, kTestsuite, "errors", "0");
48300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  OutputXmlAttribute(stream, kTestsuite, "time",
48310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                     FormatTimeInMillisAsSeconds(test_case.elapsed_time()));
48320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  *stream << TestPropertiesAsXmlAttributes(test_case.ad_hoc_test_result())
48330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          << ">\n";
48340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
48350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  for (int i = 0; i < test_case.total_test_count(); ++i) {
48360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    if (test_case.GetTestInfo(i)->is_reportable())
48370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      OutputXmlTestInfo(stream, test_case.name(), *test_case.GetTestInfo(i));
48380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
48390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  *stream << "  </" << kTestsuite << ">\n";
48400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
48410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
48420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Prints an XML summary of unit_test to output stream out.
48430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid XmlUnitTestResultPrinter::PrintXmlUnitTest(std::ostream* stream,
48440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                                const UnitTest& unit_test) {
48450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const std::string kTestsuites = "testsuites";
48460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
48470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  *stream << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
48480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  *stream << "<" << kTestsuites;
48490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
48500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  OutputXmlAttribute(stream, kTestsuites, "tests",
48510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                     StreamableToString(unit_test.reportable_test_count()));
48520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  OutputXmlAttribute(stream, kTestsuites, "failures",
48530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                     StreamableToString(unit_test.failed_test_count()));
48540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  OutputXmlAttribute(
48550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      stream, kTestsuites, "disabled",
48560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      StreamableToString(unit_test.reportable_disabled_test_count()));
48570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  OutputXmlAttribute(stream, kTestsuites, "errors", "0");
48580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  OutputXmlAttribute(
48590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      stream, kTestsuites, "timestamp",
48600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      FormatEpochTimeInMillisAsIso8601(unit_test.start_timestamp()));
48610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  OutputXmlAttribute(stream, kTestsuites, "time",
48620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                     FormatTimeInMillisAsSeconds(unit_test.elapsed_time()));
48630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
48640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (GTEST_FLAG(shuffle)) {
48650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    OutputXmlAttribute(stream, kTestsuites, "random_seed",
48660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                       StreamableToString(unit_test.random_seed()));
48670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
48680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
48690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  *stream << TestPropertiesAsXmlAttributes(unit_test.ad_hoc_test_result());
48700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
48710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  OutputXmlAttribute(stream, kTestsuites, "name", "AllTests");
48720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  *stream << ">\n";
48730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
48740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  for (int i = 0; i < unit_test.total_test_case_count(); ++i) {
48750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    if (unit_test.GetTestCase(i)->reportable_test_count() > 0)
48760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      PrintXmlTestCase(stream, *unit_test.GetTestCase(i));
48770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
48780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  *stream << "</" << kTestsuites << ">\n";
48790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
48800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
48810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Produces a string representing the test properties in a result as space
48820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// delimited XML attributes based on the property key="value" pairs.
48830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstd::string XmlUnitTestResultPrinter::TestPropertiesAsXmlAttributes(
48840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const TestResult& result) {
48850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  Message attributes;
48860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  for (int i = 0; i < result.test_property_count(); ++i) {
48870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const TestProperty& property = result.GetTestProperty(i);
48880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    attributes << " " << property.key() << "="
48890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        << "\"" << EscapeXmlAttribute(property.value()) << "\"";
48900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
48910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return attributes.GetString();
48920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
48930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
48940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// End XmlUnitTestResultPrinter
48950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
48960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#if GTEST_CAN_STREAM_RESULTS_
48970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
48980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Checks if str contains '=', '&', '%' or '\n' characters. If yes,
48990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// replaces them by "%xx" where xx is their hexadecimal value. For
49000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// example, replaces "=" with "%3D".  This algorithm is O(strlen(str))
49010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// in both time and space -- important as the input str may contain an
49020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// arbitrarily long test failure message and stack trace.
49030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstring StreamingListener::UrlEncode(const char* str) {
49040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  string result;
49050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  result.reserve(strlen(str) + 1);
49060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  for (char ch = *str; ch != '\0'; ch = *++str) {
49070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    switch (ch) {
49080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      case '%':
49090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      case '=':
49100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      case '&':
49110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      case '\n':
49120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        result.append("%" + String::FormatByte(static_cast<unsigned char>(ch)));
49130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        break;
49140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      default:
49150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        result.push_back(ch);
49160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        break;
49170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    }
49180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
49190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return result;
49200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
49210d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
49220d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid StreamingListener::SocketWriter::MakeConnection() {
49230d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  GTEST_CHECK_(sockfd_ == -1)
49240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      << "MakeConnection() can't be called when there is already a connection.";
49250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
49260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  addrinfo hints;
49270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  memset(&hints, 0, sizeof(hints));
49280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  hints.ai_family = AF_UNSPEC;    // To allow both IPv4 and IPv6 addresses.
49290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  hints.ai_socktype = SOCK_STREAM;
49300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  addrinfo* servinfo = NULL;
49310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
49320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Use the getaddrinfo() to get a linked list of IP addresses for
49330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // the given host name.
49340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const int error_num = getaddrinfo(
49350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      host_name_.c_str(), port_num_.c_str(), &hints, &servinfo);
49360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (error_num != 0) {
49370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    GTEST_LOG_(WARNING) << "stream_result_to: getaddrinfo() failed: "
49380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                        << gai_strerror(error_num);
49390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
49400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
49410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Loop through all the results and connect to the first we can.
49420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  for (addrinfo* cur_addr = servinfo; sockfd_ == -1 && cur_addr != NULL;
49430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org       cur_addr = cur_addr->ai_next) {
49440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    sockfd_ = socket(
49450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        cur_addr->ai_family, cur_addr->ai_socktype, cur_addr->ai_protocol);
49460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    if (sockfd_ != -1) {
49470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      // Connect the client socket to the server socket.
49480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      if (connect(sockfd_, cur_addr->ai_addr, cur_addr->ai_addrlen) == -1) {
49490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        close(sockfd_);
49500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        sockfd_ = -1;
49510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      }
49520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    }
49530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
49540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
49550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  freeaddrinfo(servinfo);  // all done with this structure
49560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
49570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (sockfd_ == -1) {
49580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    GTEST_LOG_(WARNING) << "stream_result_to: failed to connect to "
49590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                        << host_name_ << ":" << port_num_;
49600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
49610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
49620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
49630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// End of class Streaming Listener
49640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#endif  // GTEST_CAN_STREAM_RESULTS__
49650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
49660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Class ScopedTrace
49670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
49680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Pushes the given source file location and message onto a per-thread
49690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// trace stack maintained by Google Test.
49700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgScopedTrace::ScopedTrace(const char* file, int line, const Message& message)
49710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    GTEST_LOCK_EXCLUDED_(&UnitTest::mutex_) {
49720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  TraceInfo trace;
49730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  trace.file = file;
49740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  trace.line = line;
49750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  trace.message = message.GetString();
49760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
49770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  UnitTest::GetInstance()->PushGTestTrace(trace);
49780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
49790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
49800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Pops the info pushed by the c'tor.
49810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgScopedTrace::~ScopedTrace()
49820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    GTEST_LOCK_EXCLUDED_(&UnitTest::mutex_) {
49830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  UnitTest::GetInstance()->PopGTestTrace();
49840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
49850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
49860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
49870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// class OsStackTraceGetter
49880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
49890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Returns the current OS stack trace as an std::string.  Parameters:
49900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
49910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//   max_depth  - the maximum number of stack frames to be included
49920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//                in the trace.
49930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//   skip_count - the number of top frames to be skipped; doesn't count
49940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//                against max_depth.
49950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
49960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstring OsStackTraceGetter::CurrentStackTrace(int /* max_depth */,
49970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                             int /* skip_count */)
49980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    GTEST_LOCK_EXCLUDED_(mutex_) {
49990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return "";
50000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
50010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
50020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid OsStackTraceGetter::UponLeavingGTest()
50030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    GTEST_LOCK_EXCLUDED_(mutex_) {
50040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
50050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
50060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgconst char* const
50070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgOsStackTraceGetter::kElidedFramesMarker =
50080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    "... " GTEST_NAME_ " internal frames ...";
50090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
50100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// A helper class that creates the premature-exit file in its
50110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// constructor and deletes the file in its destructor.
50120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgclass ScopedPrematureExitFile {
50130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org public:
50140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  explicit ScopedPrematureExitFile(const char* premature_exit_filepath)
50150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      : premature_exit_filepath_(premature_exit_filepath) {
50160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // If a path to the premature-exit file is specified...
50170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    if (premature_exit_filepath != NULL && *premature_exit_filepath != '\0') {
50180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      // create the file with a single "0" character in it.  I/O
50190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      // errors are ignored as there's nothing better we can do and we
50200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      // don't want to fail the test because of this.
50210d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      FILE* pfile = posix::FOpen(premature_exit_filepath, "w");
50220d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      fwrite("0", 1, 1, pfile);
50230d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      fclose(pfile);
50240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    }
50250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
50260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
50270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  ~ScopedPrematureExitFile() {
50280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    if (premature_exit_filepath_ != NULL && *premature_exit_filepath_ != '\0') {
50290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      remove(premature_exit_filepath_);
50300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    }
50310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
50320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
50330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org private:
50340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const char* const premature_exit_filepath_;
50350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
50360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  GTEST_DISALLOW_COPY_AND_ASSIGN_(ScopedPrematureExitFile);
50370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org};
50380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
50390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}  // namespace internal
50400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
50410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// class TestEventListeners
50420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
50430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgTestEventListeners::TestEventListeners()
50440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    : repeater_(new internal::TestEventRepeater()),
50450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      default_result_printer_(NULL),
50460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      default_xml_generator_(NULL) {
50470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
50480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
50490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgTestEventListeners::~TestEventListeners() { delete repeater_; }
50500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
50510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Returns the standard listener responsible for the default console
50520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// output.  Can be removed from the listeners list to shut down default
50530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// console output.  Note that removing this object from the listener list
50540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// with Release transfers its ownership to the user.
50550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid TestEventListeners::Append(TestEventListener* listener) {
50560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  repeater_->Append(listener);
50570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
50580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
50590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Removes the given event listener from the list and returns it.  It then
50600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// becomes the caller's responsibility to delete the listener. Returns
50610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// NULL if the listener is not found in the list.
50620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgTestEventListener* TestEventListeners::Release(TestEventListener* listener) {
50630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (listener == default_result_printer_)
50640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    default_result_printer_ = NULL;
50650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  else if (listener == default_xml_generator_)
50660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    default_xml_generator_ = NULL;
50670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return repeater_->Release(listener);
50680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
50690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
50700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Returns repeater that broadcasts the TestEventListener events to all
50710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// subscribers.
50720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgTestEventListener* TestEventListeners::repeater() { return repeater_; }
50730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
50740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Sets the default_result_printer attribute to the provided listener.
50750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// The listener is also added to the listener list and previous
50760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// default_result_printer is removed from it and deleted. The listener can
50770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// also be NULL in which case it will not be added to the list. Does
50780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// nothing if the previous and the current listener objects are the same.
50790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid TestEventListeners::SetDefaultResultPrinter(TestEventListener* listener) {
50800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (default_result_printer_ != listener) {
50810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // It is an error to pass this method a listener that is already in the
50820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // list.
50830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    delete Release(default_result_printer_);
50840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    default_result_printer_ = listener;
50850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    if (listener != NULL)
50860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      Append(listener);
50870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
50880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
50890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
50900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Sets the default_xml_generator attribute to the provided listener.  The
50910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// listener is also added to the listener list and previous
50920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// default_xml_generator is removed from it and deleted. The listener can
50930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// also be NULL in which case it will not be added to the list. Does
50940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// nothing if the previous and the current listener objects are the same.
50950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid TestEventListeners::SetDefaultXmlGenerator(TestEventListener* listener) {
50960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (default_xml_generator_ != listener) {
50970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // It is an error to pass this method a listener that is already in the
50980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // list.
50990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    delete Release(default_xml_generator_);
51000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    default_xml_generator_ = listener;
51010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    if (listener != NULL)
51020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      Append(listener);
51030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
51040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
51050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
51060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Controls whether events will be forwarded by the repeater to the
51070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// listeners in the list.
51080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgbool TestEventListeners::EventForwardingEnabled() const {
51090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return repeater_->forwarding_enabled();
51100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
51110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
51120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid TestEventListeners::SuppressEventForwarding() {
51130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  repeater_->set_forwarding_enabled(false);
51140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
51150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
51160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// class UnitTest
51170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
51180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Gets the singleton UnitTest object.  The first time this method is
51190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// called, a UnitTest object is constructed and returned.  Consecutive
51200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// calls will return the same object.
51210d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
51220d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// We don't protect this under mutex_ as a user is not supposed to
51230d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// call this before main() starts, from which point on the return
51240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// value will never change.
51250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgUnitTest* UnitTest::GetInstance() {
51260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // When compiled with MSVC 7.1 in optimized mode, destroying the
51270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // UnitTest object upon exiting the program messes up the exit code,
51280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // causing successful tests to appear failed.  We have to use a
51290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // different implementation in this case to bypass the compiler bug.
51300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // This implementation makes the compiler happy, at the cost of
51310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // leaking the UnitTest object.
51320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
51330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // CodeGear C++Builder insists on a public destructor for the
51340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // default implementation.  Use this implementation to keep good OO
51350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // design with private destructor.
51360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
51370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#if (_MSC_VER == 1310 && !defined(_DEBUG)) || defined(__BORLANDC__)
51380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  static UnitTest* const instance = new UnitTest;
51390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return instance;
51400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#else
51410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  static UnitTest instance;
51420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return &instance;
51430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#endif  // (_MSC_VER == 1310 && !defined(_DEBUG)) || defined(__BORLANDC__)
51440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
51450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
51460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Gets the number of successful test cases.
51470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgint UnitTest::successful_test_case_count() const {
51480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return impl()->successful_test_case_count();
51490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
51500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
51510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Gets the number of failed test cases.
51520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgint UnitTest::failed_test_case_count() const {
51530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return impl()->failed_test_case_count();
51540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
51550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
51560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Gets the number of all test cases.
51570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgint UnitTest::total_test_case_count() const {
51580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return impl()->total_test_case_count();
51590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
51600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
51610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Gets the number of all test cases that contain at least one test
51620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// that should run.
51630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgint UnitTest::test_case_to_run_count() const {
51640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return impl()->test_case_to_run_count();
51650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
51660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
51670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Gets the number of successful tests.
51680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgint UnitTest::successful_test_count() const {
51690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return impl()->successful_test_count();
51700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
51710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
51720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Gets the number of failed tests.
51730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgint UnitTest::failed_test_count() const { return impl()->failed_test_count(); }
51740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
51750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Gets the number of disabled tests that will be reported in the XML report.
51760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgint UnitTest::reportable_disabled_test_count() const {
51770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return impl()->reportable_disabled_test_count();
51780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
51790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
51800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Gets the number of disabled tests.
51810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgint UnitTest::disabled_test_count() const {
51820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return impl()->disabled_test_count();
51830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
51840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
51850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Gets the number of tests to be printed in the XML report.
51860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgint UnitTest::reportable_test_count() const {
51870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return impl()->reportable_test_count();
51880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
51890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
51900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Gets the number of all tests.
51910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgint UnitTest::total_test_count() const { return impl()->total_test_count(); }
51920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
51930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Gets the number of tests that should run.
51940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgint UnitTest::test_to_run_count() const { return impl()->test_to_run_count(); }
51950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
51960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Gets the time of the test program start, in ms from the start of the
51970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// UNIX epoch.
51980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orginternal::TimeInMillis UnitTest::start_timestamp() const {
51990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return impl()->start_timestamp();
52000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
52010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
52020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Gets the elapsed time, in milliseconds.
52030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orginternal::TimeInMillis UnitTest::elapsed_time() const {
52040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return impl()->elapsed_time();
52050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
52060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
52070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Returns true iff the unit test passed (i.e. all test cases passed).
52080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgbool UnitTest::Passed() const { return impl()->Passed(); }
52090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
52100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Returns true iff the unit test failed (i.e. some test case failed
52110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// or something outside of all tests failed).
52120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgbool UnitTest::Failed() const { return impl()->Failed(); }
52130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
52140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Gets the i-th test case among all the test cases. i can range from 0 to
52150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// total_test_case_count() - 1. If i is not in that range, returns NULL.
52160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgconst TestCase* UnitTest::GetTestCase(int i) const {
52170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return impl()->GetTestCase(i);
52180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
52190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
52200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Returns the TestResult containing information on test failures and
52210d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// properties logged outside of individual test cases.
52220d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgconst TestResult& UnitTest::ad_hoc_test_result() const {
52230d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return *impl()->ad_hoc_test_result();
52240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
52250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
52260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Gets the i-th test case among all the test cases. i can range from 0 to
52270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// total_test_case_count() - 1. If i is not in that range, returns NULL.
52280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgTestCase* UnitTest::GetMutableTestCase(int i) {
52290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return impl()->GetMutableTestCase(i);
52300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
52310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
52320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Returns the list of event listeners that can be used to track events
52330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// inside Google Test.
52340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgTestEventListeners& UnitTest::listeners() {
52350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return *impl()->listeners();
52360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
52370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
52380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Registers and returns a global test environment.  When a test
52390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// program is run, all global test environments will be set-up in the
52400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// order they were registered.  After all tests in the program have
52410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// finished, all global test environments will be torn-down in the
52420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// *reverse* order they were registered.
52430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
52440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// The UnitTest object takes ownership of the given environment.
52450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
52460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// We don't protect this under mutex_, as we only support calling it
52470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// from the main thread.
52480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgEnvironment* UnitTest::AddEnvironment(Environment* env) {
52490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (env == NULL) {
52500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return NULL;
52510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
52520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
52530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  impl_->environments().push_back(env);
52540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return env;
52550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
52560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
52570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Adds a TestPartResult to the current TestResult object.  All Google Test
52580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// assertion macros (e.g. ASSERT_TRUE, EXPECT_EQ, etc) eventually call
52590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// this to report their results.  The user code should use the
52600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// assertion macros instead of calling this directly.
52610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid UnitTest::AddTestPartResult(
52620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    TestPartResult::Type result_type,
52630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const char* file_name,
52640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    int line_number,
52650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const std::string& message,
52660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const std::string& os_stack_trace) GTEST_LOCK_EXCLUDED_(mutex_) {
52670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  Message msg;
52680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  msg << message;
52690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
52700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  internal::MutexLock lock(&mutex_);
52710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (impl_->gtest_trace_stack().size() > 0) {
52720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    msg << "\n" << GTEST_NAME_ << " trace:";
52730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
52740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    for (int i = static_cast<int>(impl_->gtest_trace_stack().size());
52750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org         i > 0; --i) {
52760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      const internal::TraceInfo& trace = impl_->gtest_trace_stack()[i - 1];
52770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      msg << "\n" << internal::FormatFileLocation(trace.file, trace.line)
52780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          << " " << trace.message;
52790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    }
52800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
52810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
52820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (os_stack_trace.c_str() != NULL && !os_stack_trace.empty()) {
52830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    msg << internal::kStackTraceMarker << os_stack_trace;
52840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
52850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
52860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const TestPartResult result =
52870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    TestPartResult(result_type, file_name, line_number,
52880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                   msg.GetString().c_str());
52890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  impl_->GetTestPartResultReporterForCurrentThread()->
52900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      ReportTestPartResult(result);
52910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
52920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (result_type != TestPartResult::kSuccess) {
52930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // gtest_break_on_failure takes precedence over
52940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // gtest_throw_on_failure.  This allows a user to set the latter
52950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // in the code (perhaps in order to use Google Test assertions
52960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // with another testing framework) and specify the former on the
52970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // command line for debugging.
52980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    if (GTEST_FLAG(break_on_failure)) {
52990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#if GTEST_OS_WINDOWS
53000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      // Using DebugBreak on Windows allows gtest to still break into a debugger
53010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      // when a failure happens and both the --gtest_break_on_failure and
53020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      // the --gtest_catch_exceptions flags are specified.
53030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      DebugBreak();
53040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#else
53050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      // Dereference NULL through a volatile pointer to prevent the compiler
53060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      // from removing. We use this rather than abort() or __builtin_trap() for
53070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      // portability: Symbian doesn't implement abort() well, and some debuggers
53080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      // don't correctly trap abort().
53090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      *static_cast<volatile int*>(NULL) = 1;
53100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#endif  // GTEST_OS_WINDOWS
53110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    } else if (GTEST_FLAG(throw_on_failure)) {
53120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#if GTEST_HAS_EXCEPTIONS
53130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      throw internal::GoogleTestFailureException(result);
53140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#else
53150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      // We cannot call abort() as it generates a pop-up in debug mode
53160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      // that cannot be suppressed in VC 7.1 or below.
53170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      exit(1);
53180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#endif
53190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    }
53200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
53210d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
53220d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
53230d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Adds a TestProperty to the current TestResult object when invoked from
53240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// inside a test, to current TestCase's ad_hoc_test_result_ when invoked
53250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// from SetUpTestCase or TearDownTestCase, or to the global property set
53260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// when invoked elsewhere.  If the result already contains a property with
53270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// the same key, the value will be updated.
53280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid UnitTest::RecordProperty(const std::string& key,
53290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                              const std::string& value) {
53300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  impl_->RecordProperty(TestProperty(key, value));
53310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
53320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
53330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Runs all tests in this UnitTest object and prints the result.
53340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Returns 0 if successful, or 1 otherwise.
53350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
53360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// We don't protect this under mutex_, as we only support calling it
53370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// from the main thread.
53380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgint UnitTest::Run() {
53390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const bool in_death_test_child_process =
53400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      internal::GTEST_FLAG(internal_run_death_test).length() > 0;
53410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
53420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Google Test implements this protocol for catching that a test
53430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // program exits before returning control to Google Test:
53440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  //
53450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  //   1. Upon start, Google Test creates a file whose absolute path
53460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  //      is specified by the environment variable
53470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  //      TEST_PREMATURE_EXIT_FILE.
53480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  //   2. When Google Test has finished its work, it deletes the file.
53490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  //
53500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // This allows a test runner to set TEST_PREMATURE_EXIT_FILE before
53510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // running a Google-Test-based test program and check the existence
53520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // of the file at the end of the test execution to see if it has
53530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // exited prematurely.
53540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
53550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // If we are in the child process of a death test, don't
53560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // create/delete the premature exit file, as doing so is unnecessary
53570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // and will confuse the parent process.  Otherwise, create/delete
53580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // the file upon entering/leaving this function.  If the program
53590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // somehow exits before this function has a chance to return, the
53600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // premature-exit file will be left undeleted, causing a test runner
53610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // that understands the premature-exit-file protocol to report the
53620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // test as having failed.
53630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const internal::ScopedPrematureExitFile premature_exit_file(
53640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      in_death_test_child_process ?
53650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      NULL : internal::posix::GetEnv("TEST_PREMATURE_EXIT_FILE"));
53660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
53670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Captures the value of GTEST_FLAG(catch_exceptions).  This value will be
53680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // used for the duration of the program.
53690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  impl()->set_catch_exceptions(GTEST_FLAG(catch_exceptions));
53700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
53710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#if GTEST_HAS_SEH
53720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Either the user wants Google Test to catch exceptions thrown by the
53730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // tests or this is executing in the context of death test child
53740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // process. In either case the user does not want to see pop-up dialogs
53750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // about crashes - they are expected.
53760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (impl()->catch_exceptions() || in_death_test_child_process) {
53770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# if !GTEST_OS_WINDOWS_MOBILE
53780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // SetErrorMode doesn't exist on CE.
53790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOALIGNMENTFAULTEXCEPT |
53800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                 SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX);
53810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# endif  // !GTEST_OS_WINDOWS_MOBILE
53820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
53830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# if (defined(_MSC_VER) || GTEST_OS_WINDOWS_MINGW) && !GTEST_OS_WINDOWS_MOBILE
53840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // Death test children can be terminated with _abort().  On Windows,
53850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // _abort() can show a dialog with a warning message.  This forces the
53860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // abort message to go to stderr instead.
53870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    _set_error_mode(_OUT_TO_STDERR);
53880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# endif
53890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
53900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# if _MSC_VER >= 1400 && !GTEST_OS_WINDOWS_MOBILE
53910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // In the debug version, Visual Studio pops up a separate dialog
53920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // offering a choice to debug the aborted program. We need to suppress
53930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // this dialog or it will pop up for every EXPECT/ASSERT_DEATH statement
53940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // executed. Google Test will notify the user of any unexpected
53950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // failure via stderr.
53960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    //
53970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // VC++ doesn't define _set_abort_behavior() prior to the version 8.0.
53980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // Users of prior VC versions shall suffer the agony and pain of
53990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // clicking through the countless debug dialogs.
54000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // TODO(vladl@google.com): find a way to suppress the abort dialog() in the
54010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // debug mode when compiled with VC 7.1 or lower.
54020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    if (!GTEST_FLAG(break_on_failure))
54030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      _set_abort_behavior(
54040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          0x0,                                    // Clear the following flags:
54050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          _WRITE_ABORT_MSG | _CALL_REPORTFAULT);  // pop-up window, core dump.
54060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# endif
54070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
54080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#endif  // GTEST_HAS_SEH
54090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
54100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return internal::HandleExceptionsInMethodIfSupported(
54110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      impl(),
54120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      &internal::UnitTestImpl::RunAllTests,
54130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      "auxiliary test code (environments or event listeners)") ? 0 : 1;
54140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
54150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
54160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Returns the working directory when the first TEST() or TEST_F() was
54170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// executed.
54180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgconst char* UnitTest::original_working_dir() const {
54190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return impl_->original_working_dir_.c_str();
54200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
54210d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
54220d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Returns the TestCase object for the test that's currently running,
54230d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// or NULL if no test is running.
54240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgconst TestCase* UnitTest::current_test_case() const
54250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    GTEST_LOCK_EXCLUDED_(mutex_) {
54260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  internal::MutexLock lock(&mutex_);
54270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return impl_->current_test_case();
54280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
54290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
54300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Returns the TestInfo object for the test that's currently running,
54310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// or NULL if no test is running.
54320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgconst TestInfo* UnitTest::current_test_info() const
54330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    GTEST_LOCK_EXCLUDED_(mutex_) {
54340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  internal::MutexLock lock(&mutex_);
54350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return impl_->current_test_info();
54360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
54370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
54380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Returns the random seed used at the start of the current test run.
54390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgint UnitTest::random_seed() const { return impl_->random_seed(); }
54400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
54410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#if GTEST_HAS_PARAM_TEST
54420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Returns ParameterizedTestCaseRegistry object used to keep track of
54430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// value-parameterized tests and instantiate and register them.
54440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orginternal::ParameterizedTestCaseRegistry&
54450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    UnitTest::parameterized_test_registry()
54460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        GTEST_LOCK_EXCLUDED_(mutex_) {
54470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return impl_->parameterized_test_registry();
54480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
54490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#endif  // GTEST_HAS_PARAM_TEST
54500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
54510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Creates an empty UnitTest.
54520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgUnitTest::UnitTest() {
54530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  impl_ = new internal::UnitTestImpl(this);
54540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
54550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
54560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Destructor of UnitTest.
54570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgUnitTest::~UnitTest() {
54580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  delete impl_;
54590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
54600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
54610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Pushes a trace defined by SCOPED_TRACE() on to the per-thread
54620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Google Test trace stack.
54630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid UnitTest::PushGTestTrace(const internal::TraceInfo& trace)
54640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    GTEST_LOCK_EXCLUDED_(mutex_) {
54650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  internal::MutexLock lock(&mutex_);
54660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  impl_->gtest_trace_stack().push_back(trace);
54670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
54680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
54690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Pops a trace from the per-thread Google Test trace stack.
54700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid UnitTest::PopGTestTrace()
54710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    GTEST_LOCK_EXCLUDED_(mutex_) {
54720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  internal::MutexLock lock(&mutex_);
54730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  impl_->gtest_trace_stack().pop_back();
54740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
54750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
54760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgnamespace internal {
54770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
54780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgUnitTestImpl::UnitTestImpl(UnitTest* parent)
54790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    : parent_(parent),
54800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#ifdef _MSC_VER
54810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# pragma warning(push)                    // Saves the current warning state.
54820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# pragma warning(disable:4355)            // Temporarily disables warning 4355
54830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                         // (using this in initializer).
54840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      default_global_test_part_result_reporter_(this),
54850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      default_per_thread_test_part_result_reporter_(this),
54860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# pragma warning(pop)                     // Restores the warning state again.
54870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#else
54880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      default_global_test_part_result_reporter_(this),
54890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      default_per_thread_test_part_result_reporter_(this),
54900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#endif  // _MSC_VER
54910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      global_test_part_result_repoter_(
54920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          &default_global_test_part_result_reporter_),
54930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      per_thread_test_part_result_reporter_(
54940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          &default_per_thread_test_part_result_reporter_),
54950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#if GTEST_HAS_PARAM_TEST
54960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      parameterized_test_registry_(),
54970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      parameterized_tests_registered_(false),
54980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#endif  // GTEST_HAS_PARAM_TEST
54990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      last_death_test_case_(-1),
55000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      current_test_case_(NULL),
55010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      current_test_info_(NULL),
55020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      ad_hoc_test_result_(),
55030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      os_stack_trace_getter_(NULL),
55040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      post_flag_parse_init_performed_(false),
55050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      random_seed_(0),  // Will be overridden by the flag before first use.
55060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      random_(0),  // Will be reseeded before first use.
55070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      start_timestamp_(0),
55080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      elapsed_time_(0),
55090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#if GTEST_HAS_DEATH_TEST
55100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      death_test_factory_(new DefaultDeathTestFactory),
55110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#endif
55120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      // Will be overridden by the flag before first use.
55130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      catch_exceptions_(false) {
55140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  listeners()->SetDefaultResultPrinter(new PrettyUnitTestResultPrinter);
55150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
55160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
55170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgUnitTestImpl::~UnitTestImpl() {
55180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Deletes every TestCase.
55190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  ForEach(test_cases_, internal::Delete<TestCase>);
55200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
55210d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Deletes every Environment.
55220d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  ForEach(environments_, internal::Delete<Environment>);
55230d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
55240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  delete os_stack_trace_getter_;
55250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
55260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
55270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Adds a TestProperty to the current TestResult object when invoked in a
55280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// context of a test, to current test case's ad_hoc_test_result when invoke
55290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// from SetUpTestCase/TearDownTestCase, or to the global property set
55300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// otherwise.  If the result already contains a property with the same key,
55310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// the value will be updated.
55320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid UnitTestImpl::RecordProperty(const TestProperty& test_property) {
55330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  std::string xml_element;
55340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  TestResult* test_result;  // TestResult appropriate for property recording.
55350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
55360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (current_test_info_ != NULL) {
55370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    xml_element = "testcase";
55380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    test_result = &(current_test_info_->result_);
55390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  } else if (current_test_case_ != NULL) {
55400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    xml_element = "testsuite";
55410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    test_result = &(current_test_case_->ad_hoc_test_result_);
55420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  } else {
55430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    xml_element = "testsuites";
55440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    test_result = &ad_hoc_test_result_;
55450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
55460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  test_result->RecordProperty(xml_element, test_property);
55470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
55480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
55490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#if GTEST_HAS_DEATH_TEST
55500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Disables event forwarding if the control is currently in a death test
55510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// subprocess. Must not be called before InitGoogleTest.
55520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid UnitTestImpl::SuppressTestEventsIfInSubprocess() {
55530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (internal_run_death_test_flag_.get() != NULL)
55540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    listeners()->SuppressEventForwarding();
55550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
55560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#endif  // GTEST_HAS_DEATH_TEST
55570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
55580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Initializes event listeners performing XML output as specified by
55590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// UnitTestOptions. Must not be called before InitGoogleTest.
55600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid UnitTestImpl::ConfigureXmlOutput() {
55610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const std::string& output_format = UnitTestOptions::GetOutputFormat();
55620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (output_format == "xml") {
55630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    listeners()->SetDefaultXmlGenerator(new XmlUnitTestResultPrinter(
55640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        UnitTestOptions::GetAbsolutePathToOutputFile().c_str()));
55650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  } else if (output_format != "") {
55660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    printf("WARNING: unrecognized output format \"%s\" ignored.\n",
55670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org           output_format.c_str());
55680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    fflush(stdout);
55690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
55700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
55710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
55720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#if GTEST_CAN_STREAM_RESULTS_
55730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Initializes event listeners for streaming test results in string form.
55740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Must not be called before InitGoogleTest.
55750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid UnitTestImpl::ConfigureStreamingOutput() {
55760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const std::string& target = GTEST_FLAG(stream_result_to);
55770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (!target.empty()) {
55780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const size_t pos = target.find(':');
55790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    if (pos != std::string::npos) {
55800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      listeners()->Append(new StreamingListener(target.substr(0, pos),
55810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                                target.substr(pos+1)));
55820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    } else {
55830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      printf("WARNING: unrecognized streaming target \"%s\" ignored.\n",
55840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org             target.c_str());
55850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      fflush(stdout);
55860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    }
55870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
55880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
55890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#endif  // GTEST_CAN_STREAM_RESULTS_
55900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
55910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Performs initialization dependent upon flag values obtained in
55920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// ParseGoogleTestFlagsOnly.  Is called from InitGoogleTest after the call to
55930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// ParseGoogleTestFlagsOnly.  In case a user neglects to call InitGoogleTest
55940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// this function is also called from RunAllTests.  Since this function can be
55950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// called more than once, it has to be idempotent.
55960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid UnitTestImpl::PostFlagParsingInit() {
55970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Ensures that this function does not execute more than once.
55980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (!post_flag_parse_init_performed_) {
55990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    post_flag_parse_init_performed_ = true;
56000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
56010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#if GTEST_HAS_DEATH_TEST
56020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    InitDeathTestSubprocessControlInfo();
56030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    SuppressTestEventsIfInSubprocess();
56040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#endif  // GTEST_HAS_DEATH_TEST
56050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
56060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // Registers parameterized tests. This makes parameterized tests
56070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // available to the UnitTest reflection API without running
56080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // RUN_ALL_TESTS.
56090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    RegisterParameterizedTests();
56100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
56110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // Configures listeners for XML output. This makes it possible for users
56120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // to shut down the default XML output before invoking RUN_ALL_TESTS.
56130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    ConfigureXmlOutput();
56140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
56150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#if GTEST_CAN_STREAM_RESULTS_
56160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // Configures listeners for streaming test results to the specified server.
56170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    ConfigureStreamingOutput();
56180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#endif  // GTEST_CAN_STREAM_RESULTS_
56190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
56200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
56210d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
56220d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// A predicate that checks the name of a TestCase against a known
56230d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// value.
56240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
56250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// This is used for implementation of the UnitTest class only.  We put
56260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// it in the anonymous namespace to prevent polluting the outer
56270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// namespace.
56280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
56290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// TestCaseNameIs is copyable.
56300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgclass TestCaseNameIs {
56310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org public:
56320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Constructor.
56330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  explicit TestCaseNameIs(const std::string& name)
56340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      : name_(name) {}
56350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
56360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Returns true iff the name of test_case matches name_.
56370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  bool operator()(const TestCase* test_case) const {
56380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return test_case != NULL && strcmp(test_case->name(), name_.c_str()) == 0;
56390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
56400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
56410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org private:
56420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  std::string name_;
56430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org};
56440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
56450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Finds and returns a TestCase with the given name.  If one doesn't
56460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// exist, creates one and returns it.  It's the CALLER'S
56470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// RESPONSIBILITY to ensure that this function is only called WHEN THE
56480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// TESTS ARE NOT SHUFFLED.
56490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
56500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Arguments:
56510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
56520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//   test_case_name: name of the test case
56530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//   type_param:     the name of the test case's type parameter, or NULL if
56540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//                   this is not a typed or a type-parameterized test case.
56550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//   set_up_tc:      pointer to the function that sets up the test case
56560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//   tear_down_tc:   pointer to the function that tears down the test case
56570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgTestCase* UnitTestImpl::GetTestCase(const char* test_case_name,
56580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                    const char* type_param,
56590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                    Test::SetUpTestCaseFunc set_up_tc,
56600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                    Test::TearDownTestCaseFunc tear_down_tc) {
56610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Can we find a TestCase with the given name?
56620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const std::vector<TestCase*>::const_iterator test_case =
56630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      std::find_if(test_cases_.begin(), test_cases_.end(),
56640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                   TestCaseNameIs(test_case_name));
56650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
56660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (test_case != test_cases_.end())
56670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return *test_case;
56680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
56690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // No.  Let's create one.
56700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  TestCase* const new_test_case =
56710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      new TestCase(test_case_name, type_param, set_up_tc, tear_down_tc);
56720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
56730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Is this a death test case?
56740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (internal::UnitTestOptions::MatchesFilter(test_case_name,
56750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                               kDeathTestCaseFilter)) {
56760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // Yes.  Inserts the test case after the last death test case
56770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // defined so far.  This only works when the test cases haven't
56780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // been shuffled.  Otherwise we may end up running a death test
56790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // after a non-death test.
56800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    ++last_death_test_case_;
56810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    test_cases_.insert(test_cases_.begin() + last_death_test_case_,
56820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                       new_test_case);
56830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  } else {
56840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // No.  Appends to the end of the list.
56850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    test_cases_.push_back(new_test_case);
56860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
56870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
56880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  test_case_indices_.push_back(static_cast<int>(test_case_indices_.size()));
56890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return new_test_case;
56900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
56910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
56920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Helpers for setting up / tearing down the given environment.  They
56930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// are for use in the ForEach() function.
56940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstatic void SetUpEnvironment(Environment* env) { env->SetUp(); }
56950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstatic void TearDownEnvironment(Environment* env) { env->TearDown(); }
56960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
56970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Runs all tests in this UnitTest object, prints the result, and
56980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// returns true if all tests are successful.  If any exception is
56990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// thrown during a test, the test is considered to be failed, but the
57000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// rest of the tests will still be run.
57010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
57020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// When parameterized tests are enabled, it expands and registers
57030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// parameterized tests first in RegisterParameterizedTests().
57040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// All other functions called from RunAllTests() may safely assume that
57050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// parameterized tests are ready to be counted and run.
57060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgbool UnitTestImpl::RunAllTests() {
57070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Makes sure InitGoogleTest() was called.
57080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (!GTestIsInitialized()) {
57090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    printf("%s",
57100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org           "\nThis test program did NOT call ::testing::InitGoogleTest "
57110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org           "before calling RUN_ALL_TESTS().  Please fix it.\n");
57120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return false;
57130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
57140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
57150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Do not run any test if the --help flag was specified.
57160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (g_help_flag)
57170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return true;
57180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
57190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Repeats the call to the post-flag parsing initialization in case the
57200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // user didn't call InitGoogleTest.
57210d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  PostFlagParsingInit();
57220d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
57230d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Even if sharding is not on, test runners may want to use the
57240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // GTEST_SHARD_STATUS_FILE to query whether the test supports the sharding
57250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // protocol.
57260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  internal::WriteToShardStatusFileIfNeeded();
57270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
57280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // True iff we are in a subprocess for running a thread-safe-style
57290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // death test.
57300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  bool in_subprocess_for_death_test = false;
57310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
57320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#if GTEST_HAS_DEATH_TEST
57330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  in_subprocess_for_death_test = (internal_run_death_test_flag_.get() != NULL);
57340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#endif  // GTEST_HAS_DEATH_TEST
57350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
57360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const bool should_shard = ShouldShard(kTestTotalShards, kTestShardIndex,
57370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                        in_subprocess_for_death_test);
57380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
57390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Compares the full test names with the filter to decide which
57400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // tests to run.
57410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const bool has_tests_to_run = FilterTests(should_shard
57420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                              ? HONOR_SHARDING_PROTOCOL
57430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                              : IGNORE_SHARDING_PROTOCOL) > 0;
57440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
57450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Lists the tests and exits if the --gtest_list_tests flag was specified.
57460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (GTEST_FLAG(list_tests)) {
57470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // This must be called *after* FilterTests() has been called.
57480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    ListTestsMatchingFilter();
57490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return true;
57500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
57510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
57520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  random_seed_ = GTEST_FLAG(shuffle) ?
57530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      GetRandomSeedFromFlag(GTEST_FLAG(random_seed)) : 0;
57540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
57550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // True iff at least one test has failed.
57560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  bool failed = false;
57570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
57580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  TestEventListener* repeater = listeners()->repeater();
57590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
57600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  start_timestamp_ = GetTimeInMillis();
57610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  repeater->OnTestProgramStart(*parent_);
57620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
57630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // How many times to repeat the tests?  We don't want to repeat them
57640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // when we are inside the subprocess of a death test.
57650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const int repeat = in_subprocess_for_death_test ? 1 : GTEST_FLAG(repeat);
57660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Repeats forever if the repeat count is negative.
57670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const bool forever = repeat < 0;
57680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  for (int i = 0; forever || i != repeat; i++) {
57690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // We want to preserve failures generated by ad-hoc test
57700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // assertions executed before RUN_ALL_TESTS().
57710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    ClearNonAdHocTestResult();
57720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
57730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const TimeInMillis start = GetTimeInMillis();
57740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
57750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // Shuffles test cases and tests if requested.
57760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    if (has_tests_to_run && GTEST_FLAG(shuffle)) {
57770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      random()->Reseed(random_seed_);
57780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      // This should be done before calling OnTestIterationStart(),
57790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      // such that a test event listener can see the actual test order
57800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      // in the event.
57810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      ShuffleTests();
57820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    }
57830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
57840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // Tells the unit test event listeners that the tests are about to start.
57850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    repeater->OnTestIterationStart(*parent_, i);
57860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
57870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // Runs each test case if there is at least one test to run.
57880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    if (has_tests_to_run) {
57890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      // Sets up all environments beforehand.
57900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      repeater->OnEnvironmentsSetUpStart(*parent_);
57910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      ForEach(environments_, SetUpEnvironment);
57920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      repeater->OnEnvironmentsSetUpEnd(*parent_);
57930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
57940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      // Runs the tests only if there was no fatal failure during global
57950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      // set-up.
57960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      if (!Test::HasFatalFailure()) {
57970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        for (int test_index = 0; test_index < total_test_case_count();
57980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org             test_index++) {
57990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          GetMutableTestCase(test_index)->Run();
58000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        }
58010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      }
58020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
58030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      // Tears down all environments in reverse order afterwards.
58040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      repeater->OnEnvironmentsTearDownStart(*parent_);
58050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      std::for_each(environments_.rbegin(), environments_.rend(),
58060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                    TearDownEnvironment);
58070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      repeater->OnEnvironmentsTearDownEnd(*parent_);
58080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    }
58090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
58100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    elapsed_time_ = GetTimeInMillis() - start;
58110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
58120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // Tells the unit test event listener that the tests have just finished.
58130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    repeater->OnTestIterationEnd(*parent_, i);
58140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
58150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // Gets the result and clears it.
58160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    if (!Passed()) {
58170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      failed = true;
58180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    }
58190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
58200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // Restores the original test order after the iteration.  This
58210d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // allows the user to quickly repro a failure that happens in the
58220d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // N-th iteration without repeating the first (N - 1) iterations.
58230d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // This is not enclosed in "if (GTEST_FLAG(shuffle)) { ... }", in
58240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // case the user somehow changes the value of the flag somewhere
58250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // (it's always safe to unshuffle the tests).
58260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    UnshuffleTests();
58270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
58280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    if (GTEST_FLAG(shuffle)) {
58290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      // Picks a new random seed for each iteration.
58300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      random_seed_ = GetNextRandomSeed(random_seed_);
58310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    }
58320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
58330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
58340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  repeater->OnTestProgramEnd(*parent_);
58350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
58360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return !failed;
58370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
58380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
58390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Reads the GTEST_SHARD_STATUS_FILE environment variable, and creates the file
58400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// if the variable is present. If a file already exists at this location, this
58410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// function will write over it. If the variable is present, but the file cannot
58420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// be created, prints an error and exits.
58430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid WriteToShardStatusFileIfNeeded() {
58440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const char* const test_shard_file = posix::GetEnv(kTestShardStatusFile);
58450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (test_shard_file != NULL) {
58460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    FILE* const file = posix::FOpen(test_shard_file, "w");
58470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    if (file == NULL) {
58480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      ColoredPrintf(COLOR_RED,
58490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                    "Could not write to the test shard status file \"%s\" "
58500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                    "specified by the %s environment variable.\n",
58510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                    test_shard_file, kTestShardStatusFile);
58520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      fflush(stdout);
58530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      exit(EXIT_FAILURE);
58540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    }
58550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    fclose(file);
58560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
58570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
58580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
58590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Checks whether sharding is enabled by examining the relevant
58600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// environment variable values. If the variables are present,
58610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// but inconsistent (i.e., shard_index >= total_shards), prints
58620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// an error and exits. If in_subprocess_for_death_test, sharding is
58630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// disabled because it must only be applied to the original test
58640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// process. Otherwise, we could filter out death tests we intended to execute.
58650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgbool ShouldShard(const char* total_shards_env,
58660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                 const char* shard_index_env,
58670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                 bool in_subprocess_for_death_test) {
58680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (in_subprocess_for_death_test) {
58690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return false;
58700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
58710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
58720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const Int32 total_shards = Int32FromEnvOrDie(total_shards_env, -1);
58730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const Int32 shard_index = Int32FromEnvOrDie(shard_index_env, -1);
58740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
58750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (total_shards == -1 && shard_index == -1) {
58760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return false;
58770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  } else if (total_shards == -1 && shard_index != -1) {
58780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const Message msg = Message()
58790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      << "Invalid environment variables: you have "
58800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      << kTestShardIndex << " = " << shard_index
58810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      << ", but have left " << kTestTotalShards << " unset.\n";
58820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    ColoredPrintf(COLOR_RED, msg.GetString().c_str());
58830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    fflush(stdout);
58840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    exit(EXIT_FAILURE);
58850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  } else if (total_shards != -1 && shard_index == -1) {
58860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const Message msg = Message()
58870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      << "Invalid environment variables: you have "
58880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      << kTestTotalShards << " = " << total_shards
58890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      << ", but have left " << kTestShardIndex << " unset.\n";
58900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    ColoredPrintf(COLOR_RED, msg.GetString().c_str());
58910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    fflush(stdout);
58920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    exit(EXIT_FAILURE);
58930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  } else if (shard_index < 0 || shard_index >= total_shards) {
58940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const Message msg = Message()
58950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      << "Invalid environment variables: we require 0 <= "
58960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      << kTestShardIndex << " < " << kTestTotalShards
58970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      << ", but you have " << kTestShardIndex << "=" << shard_index
58980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      << ", " << kTestTotalShards << "=" << total_shards << ".\n";
58990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    ColoredPrintf(COLOR_RED, msg.GetString().c_str());
59000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    fflush(stdout);
59010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    exit(EXIT_FAILURE);
59020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
59030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
59040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return total_shards > 1;
59050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
59060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
59070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Parses the environment variable var as an Int32. If it is unset,
59080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// returns default_val. If it is not an Int32, prints an error
59090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// and aborts.
59100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgInt32 Int32FromEnvOrDie(const char* var, Int32 default_val) {
59110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const char* str_val = posix::GetEnv(var);
59120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (str_val == NULL) {
59130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return default_val;
59140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
59150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
59160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  Int32 result;
59170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (!ParseInt32(Message() << "The value of environment variable " << var,
59180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                  str_val, &result)) {
59190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    exit(EXIT_FAILURE);
59200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
59210d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return result;
59220d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
59230d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
59240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Given the total number of shards, the shard index, and the test id,
59250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// returns true iff the test should be run on this shard. The test id is
59260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// some arbitrary but unique non-negative integer assigned to each test
59270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// method. Assumes that 0 <= shard_index < total_shards.
59280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgbool ShouldRunTestOnShard(int total_shards, int shard_index, int test_id) {
59290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return (test_id % total_shards) == shard_index;
59300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
59310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
59320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Compares the name of each test with the user-specified filter to
59330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// decide whether the test should be run, then records the result in
59340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// each TestCase and TestInfo object.
59350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// If shard_tests == true, further filters tests based on sharding
59360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// variables in the environment - see
59370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// http://code.google.com/p/googletest/wiki/GoogleTestAdvancedGuide.
59380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Returns the number of tests that should run.
59390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgint UnitTestImpl::FilterTests(ReactionToSharding shard_tests) {
59400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const Int32 total_shards = shard_tests == HONOR_SHARDING_PROTOCOL ?
59410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      Int32FromEnvOrDie(kTestTotalShards, -1) : -1;
59420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const Int32 shard_index = shard_tests == HONOR_SHARDING_PROTOCOL ?
59430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      Int32FromEnvOrDie(kTestShardIndex, -1) : -1;
59440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
59450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // num_runnable_tests are the number of tests that will
59460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // run across all shards (i.e., match filter and are not disabled).
59470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // num_selected_tests are the number of tests to be run on
59480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // this shard.
59490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  int num_runnable_tests = 0;
59500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  int num_selected_tests = 0;
59510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  for (size_t i = 0; i < test_cases_.size(); i++) {
59520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    TestCase* const test_case = test_cases_[i];
59530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const std::string &test_case_name = test_case->name();
59540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    test_case->set_should_run(false);
59550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
59560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    for (size_t j = 0; j < test_case->test_info_list().size(); j++) {
59570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      TestInfo* const test_info = test_case->test_info_list()[j];
59580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      const std::string test_name(test_info->name());
59590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      // A test is disabled if test case name or test name matches
59600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      // kDisableTestFilter.
59610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      const bool is_disabled =
59620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          internal::UnitTestOptions::MatchesFilter(test_case_name,
59630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                                   kDisableTestFilter) ||
59640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          internal::UnitTestOptions::MatchesFilter(test_name,
59650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                                   kDisableTestFilter);
59660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      test_info->is_disabled_ = is_disabled;
59670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
59680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      const bool matches_filter =
59690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          internal::UnitTestOptions::FilterMatchesTest(test_case_name,
59700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                                       test_name);
59710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      test_info->matches_filter_ = matches_filter;
59720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
59730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      const bool is_runnable =
59740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          (GTEST_FLAG(also_run_disabled_tests) || !is_disabled) &&
59750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          matches_filter;
59760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
59770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      const bool is_selected = is_runnable &&
59780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          (shard_tests == IGNORE_SHARDING_PROTOCOL ||
59790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org           ShouldRunTestOnShard(total_shards, shard_index,
59800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                num_runnable_tests));
59810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
59820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      num_runnable_tests += is_runnable;
59830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      num_selected_tests += is_selected;
59840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
59850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      test_info->should_run_ = is_selected;
59860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      test_case->set_should_run(test_case->should_run() || is_selected);
59870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    }
59880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
59890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return num_selected_tests;
59900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
59910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
59920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Prints the given C-string on a single line by replacing all '\n'
59930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// characters with string "\\n".  If the output takes more than
59940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// max_length characters, only prints the first max_length characters
59950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// and "...".
59960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstatic void PrintOnOneLine(const char* str, int max_length) {
59970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (str != NULL) {
59980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    for (int i = 0; *str != '\0'; ++str) {
59990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      if (i >= max_length) {
60000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        printf("...");
60010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        break;
60020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      }
60030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      if (*str == '\n') {
60040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        printf("\\n");
60050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        i += 2;
60060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      } else {
60070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        printf("%c", *str);
60080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        ++i;
60090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      }
60100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    }
60110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
60120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
60130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
60140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Prints the names of the tests matching the user-specified filter flag.
60150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid UnitTestImpl::ListTestsMatchingFilter() {
60160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Print at most this many characters for each type/value parameter.
60170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const int kMaxParamLength = 250;
60180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
60190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  for (size_t i = 0; i < test_cases_.size(); i++) {
60200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const TestCase* const test_case = test_cases_[i];
60210d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    bool printed_test_case_name = false;
60220d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
60230d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    for (size_t j = 0; j < test_case->test_info_list().size(); j++) {
60240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      const TestInfo* const test_info =
60250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          test_case->test_info_list()[j];
60260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      if (test_info->matches_filter_) {
60270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        if (!printed_test_case_name) {
60280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          printed_test_case_name = true;
60290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          printf("%s.", test_case->name());
60300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          if (test_case->type_param() != NULL) {
60310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org            printf("  # %s = ", kTypeParamLabel);
60320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org            // We print the type parameter on a single line to make
60330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org            // the output easy to parse by a program.
60340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org            PrintOnOneLine(test_case->type_param(), kMaxParamLength);
60350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          }
60360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          printf("\n");
60370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        }
60380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        printf("  %s", test_info->name());
60390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        if (test_info->value_param() != NULL) {
60400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          printf("  # %s = ", kValueParamLabel);
60410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          // We print the value parameter on a single line to make the
60420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          // output easy to parse by a program.
60430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          PrintOnOneLine(test_info->value_param(), kMaxParamLength);
60440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        }
60450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        printf("\n");
60460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      }
60470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    }
60480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
60490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  fflush(stdout);
60500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
60510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
60520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Sets the OS stack trace getter.
60530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
60540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Does nothing if the input and the current OS stack trace getter are
60550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// the same; otherwise, deletes the old getter and makes the input the
60560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// current getter.
60570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid UnitTestImpl::set_os_stack_trace_getter(
60580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    OsStackTraceGetterInterface* getter) {
60590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (os_stack_trace_getter_ != getter) {
60600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    delete os_stack_trace_getter_;
60610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    os_stack_trace_getter_ = getter;
60620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
60630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
60640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
60650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Returns the current OS stack trace getter if it is not NULL;
60660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// otherwise, creates an OsStackTraceGetter, makes it the current
60670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// getter, and returns it.
60680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgOsStackTraceGetterInterface* UnitTestImpl::os_stack_trace_getter() {
60690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (os_stack_trace_getter_ == NULL) {
60700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    os_stack_trace_getter_ = new OsStackTraceGetter;
60710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
60720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
60730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return os_stack_trace_getter_;
60740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
60750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
60760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Returns the TestResult for the test that's currently running, or
60770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// the TestResult for the ad hoc test if no test is running.
60780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgTestResult* UnitTestImpl::current_test_result() {
60790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return current_test_info_ ?
60800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      &(current_test_info_->result_) : &ad_hoc_test_result_;
60810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
60820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
60830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Shuffles all test cases, and the tests within each test case,
60840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// making sure that death tests are still run first.
60850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid UnitTestImpl::ShuffleTests() {
60860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Shuffles the death test cases.
60870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  ShuffleRange(random(), 0, last_death_test_case_ + 1, &test_case_indices_);
60880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
60890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Shuffles the non-death test cases.
60900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  ShuffleRange(random(), last_death_test_case_ + 1,
60910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org               static_cast<int>(test_cases_.size()), &test_case_indices_);
60920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
60930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Shuffles the tests inside each test case.
60940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  for (size_t i = 0; i < test_cases_.size(); i++) {
60950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    test_cases_[i]->ShuffleTests(random());
60960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
60970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
60980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
60990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Restores the test cases and tests to their order before the first shuffle.
61000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid UnitTestImpl::UnshuffleTests() {
61010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  for (size_t i = 0; i < test_cases_.size(); i++) {
61020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // Unshuffles the tests in each test case.
61030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    test_cases_[i]->UnshuffleTests();
61040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // Resets the index of each test case.
61050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    test_case_indices_[i] = static_cast<int>(i);
61060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
61070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
61080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
61090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Returns the current OS stack trace as an std::string.
61100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
61110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// The maximum number of stack frames to be included is specified by
61120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// the gtest_stack_trace_depth flag.  The skip_count parameter
61130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// specifies the number of top frames to be skipped, which doesn't
61140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// count against the number of frames to be included.
61150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
61160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// For example, if Foo() calls Bar(), which in turn calls
61170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// GetCurrentOsStackTraceExceptTop(..., 1), Foo() will be included in
61180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// the trace but Bar() and GetCurrentOsStackTraceExceptTop() won't.
61190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstd::string GetCurrentOsStackTraceExceptTop(UnitTest* /*unit_test*/,
61200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                            int skip_count) {
61210d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // We pass skip_count + 1 to skip this wrapper function in addition
61220d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // to what the user really wants to skip.
61230d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return GetUnitTestImpl()->CurrentOsStackTraceExceptTop(skip_count + 1);
61240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
61250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
61260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Used by the GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_ macro to
61270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// suppress unreachable code warnings.
61280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgnamespace {
61290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgclass ClassUniqueToAlwaysTrue {};
61300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
61310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
61320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgbool IsTrue(bool condition) { return condition; }
61330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
61340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgbool AlwaysTrue() {
61350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#if GTEST_HAS_EXCEPTIONS
61360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // This condition is always false so AlwaysTrue() never actually throws,
61370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // but it makes the compiler think that it may throw.
61380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (IsTrue(false))
61390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    throw ClassUniqueToAlwaysTrue();
61400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#endif  // GTEST_HAS_EXCEPTIONS
61410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return true;
61420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
61430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
61440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// If *pstr starts with the given prefix, modifies *pstr to be right
61450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// past the prefix and returns true; otherwise leaves *pstr unchanged
61460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// and returns false.  None of pstr, *pstr, and prefix can be NULL.
61470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgbool SkipPrefix(const char* prefix, const char** pstr) {
61480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const size_t prefix_len = strlen(prefix);
61490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (strncmp(*pstr, prefix, prefix_len) == 0) {
61500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    *pstr += prefix_len;
61510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return true;
61520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
61530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return false;
61540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
61550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
61560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Parses a string as a command line flag.  The string should have
61570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// the format "--flag=value".  When def_optional is true, the "=value"
61580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// part can be omitted.
61590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
61600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Returns the value of the flag, or NULL if the parsing failed.
61610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgconst char* ParseFlagValue(const char* str,
61620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                           const char* flag,
61630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                           bool def_optional) {
61640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // str and flag must not be NULL.
61650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (str == NULL || flag == NULL) return NULL;
61660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
61670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // The flag must start with "--" followed by GTEST_FLAG_PREFIX_.
61680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const std::string flag_str = std::string("--") + GTEST_FLAG_PREFIX_ + flag;
61690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const size_t flag_len = flag_str.length();
61700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (strncmp(str, flag_str.c_str(), flag_len) != 0) return NULL;
61710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
61720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Skips the flag name.
61730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const char* flag_end = str + flag_len;
61740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
61750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // When def_optional is true, it's OK to not have a "=value" part.
61760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (def_optional && (flag_end[0] == '\0')) {
61770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return flag_end;
61780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
61790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
61800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // If def_optional is true and there are more characters after the
61810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // flag name, or if def_optional is false, there must be a '=' after
61820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // the flag name.
61830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (flag_end[0] != '=') return NULL;
61840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
61850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Returns the string after "=".
61860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return flag_end + 1;
61870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
61880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
61890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Parses a string for a bool flag, in the form of either
61900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// "--flag=value" or "--flag".
61910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
61920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// In the former case, the value is taken as true as long as it does
61930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// not start with '0', 'f', or 'F'.
61940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
61950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// In the latter case, the value is taken as true.
61960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
61970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// On success, stores the value of the flag in *value, and returns
61980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// true.  On failure, returns false without changing *value.
61990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgbool ParseBoolFlag(const char* str, const char* flag, bool* value) {
62000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Gets the value of the flag as a string.
62010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const char* const value_str = ParseFlagValue(str, flag, true);
62020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
62030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Aborts if the parsing failed.
62040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (value_str == NULL) return false;
62050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
62060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Converts the string value to a bool.
62070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  *value = !(*value_str == '0' || *value_str == 'f' || *value_str == 'F');
62080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return true;
62090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
62100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
62110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Parses a string for an Int32 flag, in the form of
62120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// "--flag=value".
62130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
62140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// On success, stores the value of the flag in *value, and returns
62150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// true.  On failure, returns false without changing *value.
62160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgbool ParseInt32Flag(const char* str, const char* flag, Int32* value) {
62170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Gets the value of the flag as a string.
62180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const char* const value_str = ParseFlagValue(str, flag, false);
62190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
62200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Aborts if the parsing failed.
62210d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (value_str == NULL) return false;
62220d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
62230d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Sets *value to the value of the flag.
62240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return ParseInt32(Message() << "The value of flag --" << flag,
62250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                    value_str, value);
62260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
62270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
62280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Parses a string for a string flag, in the form of
62290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// "--flag=value".
62300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
62310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// On success, stores the value of the flag in *value, and returns
62320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// true.  On failure, returns false without changing *value.
62330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgbool ParseStringFlag(const char* str, const char* flag, std::string* value) {
62340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Gets the value of the flag as a string.
62350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const char* const value_str = ParseFlagValue(str, flag, false);
62360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
62370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Aborts if the parsing failed.
62380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (value_str == NULL) return false;
62390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
62400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Sets *value to the value of the flag.
62410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  *value = value_str;
62420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return true;
62430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
62440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
62450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Determines whether a string has a prefix that Google Test uses for its
62460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// flags, i.e., starts with GTEST_FLAG_PREFIX_ or GTEST_FLAG_PREFIX_DASH_.
62470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// If Google Test detects that a command line flag has its prefix but is not
62480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// recognized, it will print its help message. Flags starting with
62490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// GTEST_INTERNAL_PREFIX_ followed by "internal_" are considered Google Test
62500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// internal flags and do not trigger the help message.
62510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstatic bool HasGoogleTestFlagPrefix(const char* str) {
62520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return (SkipPrefix("--", &str) ||
62530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          SkipPrefix("-", &str) ||
62540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          SkipPrefix("/", &str)) &&
62550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org         !SkipPrefix(GTEST_FLAG_PREFIX_ "internal_", &str) &&
62560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org         (SkipPrefix(GTEST_FLAG_PREFIX_, &str) ||
62570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          SkipPrefix(GTEST_FLAG_PREFIX_DASH_, &str));
62580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
62590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
62600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Prints a string containing code-encoded text.  The following escape
62610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// sequences can be used in the string to control the text color:
62620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
62630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//   @@    prints a single '@' character.
62640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//   @R    changes the color to red.
62650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//   @G    changes the color to green.
62660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//   @Y    changes the color to yellow.
62670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//   @D    changes to the default terminal text color.
62680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
62690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// TODO(wan@google.com): Write tests for this once we add stdout
62700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// capturing to Google Test.
62710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstatic void PrintColorEncoded(const char* str) {
62720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  GTestColor color = COLOR_DEFAULT;  // The current color.
62730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
62740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Conceptually, we split the string into segments divided by escape
62750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // sequences.  Then we print one segment at a time.  At the end of
62760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // each iteration, the str pointer advances to the beginning of the
62770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // next segment.
62780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  for (;;) {
62790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const char* p = strchr(str, '@');
62800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    if (p == NULL) {
62810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      ColoredPrintf(color, "%s", str);
62820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      return;
62830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    }
62840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
62850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    ColoredPrintf(color, "%s", std::string(str, p).c_str());
62860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
62870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const char ch = p[1];
62880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    str = p + 2;
62890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    if (ch == '@') {
62900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      ColoredPrintf(color, "@");
62910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    } else if (ch == 'D') {
62920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      color = COLOR_DEFAULT;
62930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    } else if (ch == 'R') {
62940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      color = COLOR_RED;
62950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    } else if (ch == 'G') {
62960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      color = COLOR_GREEN;
62970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    } else if (ch == 'Y') {
62980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      color = COLOR_YELLOW;
62990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    } else {
63000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      --str;
63010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    }
63020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
63030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
63040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
63050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstatic const char kColorEncodedHelpMessage[] =
63060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org"This program contains tests written using " GTEST_NAME_ ". You can use the\n"
63070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org"following command line flags to control its behavior:\n"
63080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org"\n"
63090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org"Test Selection:\n"
63100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org"  @G--" GTEST_FLAG_PREFIX_ "list_tests@D\n"
63110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org"      List the names of all tests instead of running them. The name of\n"
63120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org"      TEST(Foo, Bar) is \"Foo.Bar\".\n"
63130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org"  @G--" GTEST_FLAG_PREFIX_ "filter=@YPOSTIVE_PATTERNS"
63140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    "[@G-@YNEGATIVE_PATTERNS]@D\n"
63150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org"      Run only the tests whose name matches one of the positive patterns but\n"
63160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org"      none of the negative patterns. '?' matches any single character; '*'\n"
63170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org"      matches any substring; ':' separates two patterns.\n"
63180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org"  @G--" GTEST_FLAG_PREFIX_ "also_run_disabled_tests@D\n"
63190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org"      Run all disabled tests too.\n"
63200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org"\n"
63210d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org"Test Execution:\n"
63220d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org"  @G--" GTEST_FLAG_PREFIX_ "repeat=@Y[COUNT]@D\n"
63230d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org"      Run the tests repeatedly; use a negative count to repeat forever.\n"
63240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org"  @G--" GTEST_FLAG_PREFIX_ "shuffle@D\n"
63250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org"      Randomize tests' orders on every iteration.\n"
63260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org"  @G--" GTEST_FLAG_PREFIX_ "random_seed=@Y[NUMBER]@D\n"
63270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org"      Random number seed to use for shuffling test orders (between 1 and\n"
63280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org"      99999, or 0 to use a seed based on the current time).\n"
63290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org"\n"
63300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org"Test Output:\n"
63310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org"  @G--" GTEST_FLAG_PREFIX_ "color=@Y(@Gyes@Y|@Gno@Y|@Gauto@Y)@D\n"
63320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org"      Enable/disable colored output. The default is @Gauto@D.\n"
63330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org"  -@G-" GTEST_FLAG_PREFIX_ "print_time=0@D\n"
63340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org"      Don't print the elapsed time of each test.\n"
63350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org"  @G--" GTEST_FLAG_PREFIX_ "output=xml@Y[@G:@YDIRECTORY_PATH@G"
63360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    GTEST_PATH_SEP_ "@Y|@G:@YFILE_PATH]@D\n"
63370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org"      Generate an XML report in the given directory or with the given file\n"
63380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org"      name. @YFILE_PATH@D defaults to @Gtest_details.xml@D.\n"
63390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#if GTEST_CAN_STREAM_RESULTS_
63400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org"  @G--" GTEST_FLAG_PREFIX_ "stream_result_to=@YHOST@G:@YPORT@D\n"
63410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org"      Stream test results to the given server.\n"
63420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#endif  // GTEST_CAN_STREAM_RESULTS_
63430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org"\n"
63440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org"Assertion Behavior:\n"
63450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#if GTEST_HAS_DEATH_TEST && !GTEST_OS_WINDOWS
63460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org"  @G--" GTEST_FLAG_PREFIX_ "death_test_style=@Y(@Gfast@Y|@Gthreadsafe@Y)@D\n"
63470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org"      Set the default death test style.\n"
63480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#endif  // GTEST_HAS_DEATH_TEST && !GTEST_OS_WINDOWS
63490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org"  @G--" GTEST_FLAG_PREFIX_ "break_on_failure@D\n"
63500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org"      Turn assertion failures into debugger break-points.\n"
63510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org"  @G--" GTEST_FLAG_PREFIX_ "throw_on_failure@D\n"
63520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org"      Turn assertion failures into C++ exceptions.\n"
63530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org"  @G--" GTEST_FLAG_PREFIX_ "catch_exceptions=0@D\n"
63540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org"      Do not report exceptions as test failures. Instead, allow them\n"
63550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org"      to crash the program or throw a pop-up (on Windows).\n"
63560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org"\n"
63570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org"Except for @G--" GTEST_FLAG_PREFIX_ "list_tests@D, you can alternatively set "
63580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    "the corresponding\n"
63590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org"environment variable of a flag (all letters in upper-case). For example, to\n"
63600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org"disable colored text output, you can either specify @G--" GTEST_FLAG_PREFIX_
63610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    "color=no@D or set\n"
63620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org"the @G" GTEST_FLAG_PREFIX_UPPER_ "COLOR@D environment variable to @Gno@D.\n"
63630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org"\n"
63640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org"For more information, please read the " GTEST_NAME_ " documentation at\n"
63650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org"@G" GTEST_PROJECT_URL_ "@D. If you find a bug in " GTEST_NAME_ "\n"
63660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org"(not one in your own code or tests), please report it to\n"
63670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org"@G<" GTEST_DEV_EMAIL_ ">@D.\n";
63680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
63690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Parses the command line for Google Test flags, without initializing
63700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// other parts of Google Test.  The type parameter CharType can be
63710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// instantiated to either char or wchar_t.
63720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgtemplate <typename CharType>
63730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid ParseGoogleTestFlagsOnlyImpl(int* argc, CharType** argv) {
63740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  for (int i = 1; i < *argc; i++) {
63750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const std::string arg_string = StreamableToString(argv[i]);
63760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const char* const arg = arg_string.c_str();
63770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
63780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    using internal::ParseBoolFlag;
63790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    using internal::ParseInt32Flag;
63800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    using internal::ParseStringFlag;
63810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
63820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // Do we see a Google Test flag?
63830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    if (ParseBoolFlag(arg, kAlsoRunDisabledTestsFlag,
63840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                      &GTEST_FLAG(also_run_disabled_tests)) ||
63850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        ParseBoolFlag(arg, kBreakOnFailureFlag,
63860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                      &GTEST_FLAG(break_on_failure)) ||
63870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        ParseBoolFlag(arg, kCatchExceptionsFlag,
63880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                      &GTEST_FLAG(catch_exceptions)) ||
63890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        ParseStringFlag(arg, kColorFlag, &GTEST_FLAG(color)) ||
63900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        ParseStringFlag(arg, kDeathTestStyleFlag,
63910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                        &GTEST_FLAG(death_test_style)) ||
63920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        ParseBoolFlag(arg, kDeathTestUseFork,
63930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                      &GTEST_FLAG(death_test_use_fork)) ||
63940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        ParseStringFlag(arg, kFilterFlag, &GTEST_FLAG(filter)) ||
63950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        ParseStringFlag(arg, kInternalRunDeathTestFlag,
63960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                        &GTEST_FLAG(internal_run_death_test)) ||
63970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        ParseBoolFlag(arg, kListTestsFlag, &GTEST_FLAG(list_tests)) ||
63980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        ParseStringFlag(arg, kOutputFlag, &GTEST_FLAG(output)) ||
63990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        ParseBoolFlag(arg, kPrintTimeFlag, &GTEST_FLAG(print_time)) ||
64000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        ParseInt32Flag(arg, kRandomSeedFlag, &GTEST_FLAG(random_seed)) ||
64010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        ParseInt32Flag(arg, kRepeatFlag, &GTEST_FLAG(repeat)) ||
64020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        ParseBoolFlag(arg, kShuffleFlag, &GTEST_FLAG(shuffle)) ||
64030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        ParseInt32Flag(arg, kStackTraceDepthFlag,
64040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                       &GTEST_FLAG(stack_trace_depth)) ||
64050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        ParseStringFlag(arg, kStreamResultToFlag,
64060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                        &GTEST_FLAG(stream_result_to)) ||
64070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        ParseBoolFlag(arg, kThrowOnFailureFlag,
64080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                      &GTEST_FLAG(throw_on_failure))
64090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        ) {
64100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      // Yes.  Shift the remainder of the argv list left by one.  Note
64110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      // that argv has (*argc + 1) elements, the last one always being
64120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      // NULL.  The following loop moves the trailing NULL element as
64130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      // well.
64140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      for (int j = i; j != *argc; j++) {
64150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        argv[j] = argv[j + 1];
64160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      }
64170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
64180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      // Decrements the argument count.
64190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      (*argc)--;
64200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
64210d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      // We also need to decrement the iterator as we just removed
64220d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      // an element.
64230d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      i--;
64240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    } else if (arg_string == "--help" || arg_string == "-h" ||
64250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org               arg_string == "-?" || arg_string == "/?" ||
64260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org               HasGoogleTestFlagPrefix(arg)) {
64270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      // Both help flag and unrecognized Google Test flags (excluding
64280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      // internal ones) trigger help display.
64290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      g_help_flag = true;
64300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    }
64310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
64320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
64330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (g_help_flag) {
64340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // We print the help here instead of in RUN_ALL_TESTS(), as the
64350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // latter may not be called at all if the user is using Google
64360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // Test with another testing framework.
64370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    PrintColorEncoded(kColorEncodedHelpMessage);
64380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
64390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
64400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
64410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Parses the command line for Google Test flags, without initializing
64420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// other parts of Google Test.
64430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid ParseGoogleTestFlagsOnly(int* argc, char** argv) {
64440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  ParseGoogleTestFlagsOnlyImpl(argc, argv);
64450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
64460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid ParseGoogleTestFlagsOnly(int* argc, wchar_t** argv) {
64470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  ParseGoogleTestFlagsOnlyImpl(argc, argv);
64480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
64490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
64500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// The internal implementation of InitGoogleTest().
64510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
64520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// The type parameter CharType can be instantiated to either char or
64530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// wchar_t.
64540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgtemplate <typename CharType>
64550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid InitGoogleTestImpl(int* argc, CharType** argv) {
64560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  g_init_gtest_count++;
64570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
64580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // We don't want to run the initialization code twice.
64590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (g_init_gtest_count != 1) return;
64600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
64610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (*argc <= 0) return;
64620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
64630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  internal::g_executable_path = internal::StreamableToString(argv[0]);
64640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
64650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#if GTEST_HAS_DEATH_TEST
64660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
64670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  g_argvs.clear();
64680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  for (int i = 0; i != *argc; i++) {
64690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    g_argvs.push_back(StreamableToString(argv[i]));
64700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
64710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
64720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#endif  // GTEST_HAS_DEATH_TEST
64730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
64740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  ParseGoogleTestFlagsOnly(argc, argv);
64750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  GetUnitTestImpl()->PostFlagParsingInit();
64760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
64770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
64780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}  // namespace internal
64790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
64800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Initializes Google Test.  This must be called before calling
64810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// RUN_ALL_TESTS().  In particular, it parses a command line for the
64820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// flags that Google Test recognizes.  Whenever a Google Test flag is
64830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// seen, it is removed from argv, and *argc is decremented.
64840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
64850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// No value is returned.  Instead, the Google Test flag variables are
64860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// updated.
64870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
64880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Calling the function for the second time has no user-visible effect.
64890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid InitGoogleTest(int* argc, char** argv) {
64900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  internal::InitGoogleTestImpl(argc, argv);
64910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
64920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
64930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// This overloaded version can be used in Windows programs compiled in
64940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// UNICODE mode.
64950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid InitGoogleTest(int* argc, wchar_t** argv) {
64960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  internal::InitGoogleTestImpl(argc, argv);
64970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
64980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
64990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}  // namespace testing
65000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Copyright 2005, Google Inc.
65010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// All rights reserved.
65020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
65030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Redistribution and use in source and binary forms, with or without
65040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// modification, are permitted provided that the following conditions are
65050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// met:
65060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
65070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//     * Redistributions of source code must retain the above copyright
65080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// notice, this list of conditions and the following disclaimer.
65090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//     * Redistributions in binary form must reproduce the above
65100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// copyright notice, this list of conditions and the following disclaimer
65110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// in the documentation and/or other materials provided with the
65120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// distribution.
65130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//     * Neither the name of Google Inc. nor the names of its
65140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// contributors may be used to endorse or promote products derived from
65150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// this software without specific prior written permission.
65160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
65170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
65180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
65190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
65200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
65210d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
65220d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
65230d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
65240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
65250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
65260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
65270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
65280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
65290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Author: wan@google.com (Zhanyong Wan), vladl@google.com (Vlad Losev)
65300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
65310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// This file implements death tests.
65320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
65330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
65340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#if GTEST_HAS_DEATH_TEST
65350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
65360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# if GTEST_OS_MAC
65370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#  include <crt_externs.h>
65380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# endif  // GTEST_OS_MAC
65390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
65400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# include <errno.h>
65410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# include <fcntl.h>
65420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# include <limits.h>
65430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
65440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# if GTEST_OS_LINUX
65450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#  include <signal.h>
65460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# endif  // GTEST_OS_LINUX
65470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
65480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# include <stdarg.h>
65490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
65500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# if GTEST_OS_WINDOWS
65510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#  include <windows.h>
65520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# else
65530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#  include <sys/mman.h>
65540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#  include <sys/wait.h>
65550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# endif  // GTEST_OS_WINDOWS
65560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
65570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# if GTEST_OS_QNX
65580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#  include <spawn.h>
65590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# endif  // GTEST_OS_QNX
65600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
65610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#endif  // GTEST_HAS_DEATH_TEST
65620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
65630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
65640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Indicates that this translation unit is part of Google Test's
65650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// implementation.  It must come before gtest-internal-inl.h is
65660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// included, or there will be a compiler error.  This trick is to
65670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// prevent a user from accidentally including gtest-internal-inl.h in
65680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// his code.
65690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#define GTEST_IMPLEMENTATION_ 1
65700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#undef GTEST_IMPLEMENTATION_
65710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
65720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgnamespace testing {
65730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
65740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Constants.
65750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
65760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// The default death test style.
65770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstatic const char kDefaultDeathTestStyle[] = "fast";
65780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
65790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgGTEST_DEFINE_string_(
65800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    death_test_style,
65810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    internal::StringFromGTestEnv("death_test_style", kDefaultDeathTestStyle),
65820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    "Indicates how to run a death test in a forked child process: "
65830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    "\"threadsafe\" (child process re-executes the test binary "
65840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    "from the beginning, running only the specific death test) or "
65850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    "\"fast\" (child process runs the death test immediately "
65860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    "after forking).");
65870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
65880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgGTEST_DEFINE_bool_(
65890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    death_test_use_fork,
65900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    internal::BoolFromGTestEnv("death_test_use_fork", false),
65910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    "Instructs to use fork()/_exit() instead of clone() in death tests. "
65920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    "Ignored and always uses fork() on POSIX systems where clone() is not "
65930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    "implemented. Useful when running under valgrind or similar tools if "
65940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    "those do not support clone(). Valgrind 3.3.1 will just fail if "
65950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    "it sees an unsupported combination of clone() flags. "
65960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    "It is not recommended to use this flag w/o valgrind though it will "
65970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    "work in 99% of the cases. Once valgrind is fixed, this flag will "
65980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    "most likely be removed.");
65990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
66000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgnamespace internal {
66010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgGTEST_DEFINE_string_(
66020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    internal_run_death_test, "",
66030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    "Indicates the file, line number, temporal index of "
66040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    "the single death test to run, and a file descriptor to "
66050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    "which a success code may be sent, all separated by "
66060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    "the '|' characters.  This flag is specified if and only if the current "
66070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    "process is a sub-process launched for running a thread-safe "
66080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    "death test.  FOR INTERNAL USE ONLY.");
66090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}  // namespace internal
66100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
66110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#if GTEST_HAS_DEATH_TEST
66120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
66130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgnamespace internal {
66140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
66150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Valid only for fast death tests. Indicates the code is running in the
66160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// child process of a fast style death test.
66170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstatic bool g_in_fast_death_test_child = false;
66180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
66190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Returns a Boolean value indicating whether the caller is currently
66200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// executing in the context of the death test child process.  Tools such as
66210d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Valgrind heap checkers may need this to modify their behavior in death
66220d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// tests.  IMPORTANT: This is an internal utility.  Using it may break the
66230d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// implementation of death tests.  User code MUST NOT use it.
66240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgbool InDeathTestChild() {
66250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# if GTEST_OS_WINDOWS
66260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
66270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // On Windows, death tests are thread-safe regardless of the value of the
66280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // death_test_style flag.
66290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return !GTEST_FLAG(internal_run_death_test).empty();
66300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
66310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# else
66320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
66330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (GTEST_FLAG(death_test_style) == "threadsafe")
66340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return !GTEST_FLAG(internal_run_death_test).empty();
66350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  else
66360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return g_in_fast_death_test_child;
66370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#endif
66380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
66390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
66400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}  // namespace internal
66410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
66420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// ExitedWithCode constructor.
66430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgExitedWithCode::ExitedWithCode(int exit_code) : exit_code_(exit_code) {
66440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
66450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
66460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// ExitedWithCode function-call operator.
66470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgbool ExitedWithCode::operator()(int exit_status) const {
66480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# if GTEST_OS_WINDOWS
66490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
66500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return exit_status == exit_code_;
66510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
66520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# else
66530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
66540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return WIFEXITED(exit_status) && WEXITSTATUS(exit_status) == exit_code_;
66550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
66560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# endif  // GTEST_OS_WINDOWS
66570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
66580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
66590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# if !GTEST_OS_WINDOWS
66600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// KilledBySignal constructor.
66610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgKilledBySignal::KilledBySignal(int signum) : signum_(signum) {
66620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
66630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
66640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// KilledBySignal function-call operator.
66650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgbool KilledBySignal::operator()(int exit_status) const {
66660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return WIFSIGNALED(exit_status) && WTERMSIG(exit_status) == signum_;
66670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
66680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# endif  // !GTEST_OS_WINDOWS
66690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
66700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgnamespace internal {
66710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
66720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Utilities needed for death tests.
66730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
66740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Generates a textual description of a given exit code, in the format
66750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// specified by wait(2).
66760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstatic std::string ExitSummary(int exit_code) {
66770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  Message m;
66780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
66790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# if GTEST_OS_WINDOWS
66800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
66810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  m << "Exited with exit status " << exit_code;
66820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
66830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# else
66840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
66850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (WIFEXITED(exit_code)) {
66860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    m << "Exited with exit status " << WEXITSTATUS(exit_code);
66870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  } else if (WIFSIGNALED(exit_code)) {
66880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    m << "Terminated by signal " << WTERMSIG(exit_code);
66890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
66900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#  ifdef WCOREDUMP
66910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (WCOREDUMP(exit_code)) {
66920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    m << " (core dumped)";
66930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
66940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#  endif
66950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# endif  // GTEST_OS_WINDOWS
66960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
66970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return m.GetString();
66980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
66990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
67000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Returns true if exit_status describes a process that was terminated
67010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// by a signal, or exited normally with a nonzero exit code.
67020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgbool ExitedUnsuccessfully(int exit_status) {
67030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return !ExitedWithCode(0)(exit_status);
67040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
67050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
67060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# if !GTEST_OS_WINDOWS
67070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Generates a textual failure message when a death test finds more than
67080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// one thread running, or cannot determine the number of threads, prior
67090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// to executing the given statement.  It is the responsibility of the
67100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// caller not to pass a thread_count of 1.
67110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstatic std::string DeathTestThreadWarning(size_t thread_count) {
67120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  Message msg;
67130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  msg << "Death tests use fork(), which is unsafe particularly"
67140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      << " in a threaded context. For this test, " << GTEST_NAME_ << " ";
67150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (thread_count == 0)
67160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    msg << "couldn't detect the number of threads.";
67170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  else
67180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    msg << "detected " << thread_count << " threads.";
67190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return msg.GetString();
67200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
67210d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# endif  // !GTEST_OS_WINDOWS
67220d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
67230d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Flag characters for reporting a death test that did not die.
67240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstatic const char kDeathTestLived = 'L';
67250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstatic const char kDeathTestReturned = 'R';
67260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstatic const char kDeathTestThrew = 'T';
67270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstatic const char kDeathTestInternalError = 'I';
67280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
67290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// An enumeration describing all of the possible ways that a death test can
67300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// conclude.  DIED means that the process died while executing the test
67310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// code; LIVED means that process lived beyond the end of the test code;
67320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// RETURNED means that the test statement attempted to execute a return
67330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// statement, which is not allowed; THREW means that the test statement
67340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// returned control by throwing an exception.  IN_PROGRESS means the test
67350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// has not yet concluded.
67360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// TODO(vladl@google.com): Unify names and possibly values for
67370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// AbortReason, DeathTestOutcome, and flag characters above.
67380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgenum DeathTestOutcome { IN_PROGRESS, DIED, LIVED, RETURNED, THREW };
67390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
67400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Routine for aborting the program which is safe to call from an
67410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// exec-style death test child process, in which case the error
67420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// message is propagated back to the parent process.  Otherwise, the
67430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// message is simply printed to stderr.  In either case, the program
67440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// then exits with status 1.
67450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid DeathTestAbort(const std::string& message) {
67460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // On a POSIX system, this function may be called from a threadsafe-style
67470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // death test child process, which operates on a very small stack.  Use
67480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // the heap for any additional non-minuscule memory requirements.
67490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const InternalRunDeathTestFlag* const flag =
67500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      GetUnitTestImpl()->internal_run_death_test_flag();
67510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (flag != NULL) {
67520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    FILE* parent = posix::FDOpen(flag->write_fd(), "w");
67530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    fputc(kDeathTestInternalError, parent);
67540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    fprintf(parent, "%s", message.c_str());
67550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    fflush(parent);
67560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    _exit(1);
67570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  } else {
67580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    fprintf(stderr, "%s", message.c_str());
67590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    fflush(stderr);
67600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    posix::Abort();
67610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
67620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
67630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
67640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// A replacement for CHECK that calls DeathTestAbort if the assertion
67650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// fails.
67660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# define GTEST_DEATH_TEST_CHECK_(expression) \
67670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  do { \
67680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    if (!::testing::internal::IsTrue(expression)) { \
67690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      DeathTestAbort( \
67700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          ::std::string("CHECK failed: File ") + __FILE__ +  ", line " \
67710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          + ::testing::internal::StreamableToString(__LINE__) + ": " \
67720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          + #expression); \
67730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    } \
67740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  } while (::testing::internal::AlwaysFalse())
67750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
67760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// This macro is similar to GTEST_DEATH_TEST_CHECK_, but it is meant for
67770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// evaluating any system call that fulfills two conditions: it must return
67780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// -1 on failure, and set errno to EINTR when it is interrupted and
67790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// should be tried again.  The macro expands to a loop that repeatedly
67800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// evaluates the expression as long as it evaluates to -1 and sets
67810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// errno to EINTR.  If the expression evaluates to -1 but errno is
67820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// something other than EINTR, DeathTestAbort is called.
67830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# define GTEST_DEATH_TEST_CHECK_SYSCALL_(expression) \
67840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  do { \
67850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    int gtest_retval; \
67860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    do { \
67870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      gtest_retval = (expression); \
67880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    } while (gtest_retval == -1 && errno == EINTR); \
67890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    if (gtest_retval == -1) { \
67900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      DeathTestAbort( \
67910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          ::std::string("CHECK failed: File ") + __FILE__ + ", line " \
67920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          + ::testing::internal::StreamableToString(__LINE__) + ": " \
67930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          + #expression + " != -1"); \
67940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    } \
67950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  } while (::testing::internal::AlwaysFalse())
67960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
67970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Returns the message describing the last system error in errno.
67980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstd::string GetLastErrnoDescription() {
67990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return errno == 0 ? "" : posix::StrError(errno);
68000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
68010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
68020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// This is called from a death test parent process to read a failure
68030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// message from the death test child process and log it with the FATAL
68040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// severity. On Windows, the message is read from a pipe handle. On other
68050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// platforms, it is read from a file descriptor.
68060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstatic void FailFromInternalError(int fd) {
68070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  Message error;
68080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  char buffer[256];
68090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  int num_read;
68100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
68110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  do {
68120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    while ((num_read = posix::Read(fd, buffer, 255)) > 0) {
68130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      buffer[num_read] = '\0';
68140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      error << buffer;
68150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    }
68160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  } while (num_read == -1 && errno == EINTR);
68170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
68180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (num_read == 0) {
68190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    GTEST_LOG_(FATAL) << error.GetString();
68200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  } else {
68210d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const int last_error = errno;
68220d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    GTEST_LOG_(FATAL) << "Error while reading death test internal: "
68230d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                      << GetLastErrnoDescription() << " [" << last_error << "]";
68240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
68250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
68260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
68270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Death test constructor.  Increments the running death test count
68280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// for the current test.
68290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgDeathTest::DeathTest() {
68300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  TestInfo* const info = GetUnitTestImpl()->current_test_info();
68310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (info == NULL) {
68320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    DeathTestAbort("Cannot run a death test outside of a TEST or "
68330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                   "TEST_F construct");
68340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
68350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
68360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
68370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Creates and returns a death test by dispatching to the current
68380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// death test factory.
68390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgbool DeathTest::Create(const char* statement, const RE* regex,
68400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                       const char* file, int line, DeathTest** test) {
68410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return GetUnitTestImpl()->death_test_factory()->Create(
68420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      statement, regex, file, line, test);
68430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
68440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
68450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgconst char* DeathTest::LastMessage() {
68460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return last_death_test_message_.c_str();
68470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
68480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
68490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid DeathTest::set_last_death_test_message(const std::string& message) {
68500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  last_death_test_message_ = message;
68510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
68520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
68530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstd::string DeathTest::last_death_test_message_;
68540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
68550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Provides cross platform implementation for some death functionality.
68560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgclass DeathTestImpl : public DeathTest {
68570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org protected:
68580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  DeathTestImpl(const char* a_statement, const RE* a_regex)
68590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      : statement_(a_statement),
68600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        regex_(a_regex),
68610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        spawned_(false),
68620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        status_(-1),
68630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        outcome_(IN_PROGRESS),
68640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        read_fd_(-1),
68650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        write_fd_(-1) {}
68660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
68670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // read_fd_ is expected to be closed and cleared by a derived class.
68680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  ~DeathTestImpl() { GTEST_DEATH_TEST_CHECK_(read_fd_ == -1); }
68690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
68700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  void Abort(AbortReason reason);
68710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  virtual bool Passed(bool status_ok);
68720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
68730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const char* statement() const { return statement_; }
68740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const RE* regex() const { return regex_; }
68750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  bool spawned() const { return spawned_; }
68760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  void set_spawned(bool is_spawned) { spawned_ = is_spawned; }
68770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  int status() const { return status_; }
68780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  void set_status(int a_status) { status_ = a_status; }
68790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  DeathTestOutcome outcome() const { return outcome_; }
68800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  void set_outcome(DeathTestOutcome an_outcome) { outcome_ = an_outcome; }
68810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  int read_fd() const { return read_fd_; }
68820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  void set_read_fd(int fd) { read_fd_ = fd; }
68830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  int write_fd() const { return write_fd_; }
68840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  void set_write_fd(int fd) { write_fd_ = fd; }
68850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
68860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Called in the parent process only. Reads the result code of the death
68870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // test child process via a pipe, interprets it to set the outcome_
68880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // member, and closes read_fd_.  Outputs diagnostics and terminates in
68890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // case of unexpected codes.
68900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  void ReadAndInterpretStatusByte();
68910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
68920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org private:
68930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // The textual content of the code this object is testing.  This class
68940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // doesn't own this string and should not attempt to delete it.
68950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const char* const statement_;
68960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // The regular expression which test output must match.  DeathTestImpl
68970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // doesn't own this object and should not attempt to delete it.
68980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const RE* const regex_;
68990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // True if the death test child process has been successfully spawned.
69000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  bool spawned_;
69010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // The exit status of the child process.
69020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  int status_;
69030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // How the death test concluded.
69040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  DeathTestOutcome outcome_;
69050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Descriptor to the read end of the pipe to the child process.  It is
69060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // always -1 in the child process.  The child keeps its write end of the
69070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // pipe in write_fd_.
69080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  int read_fd_;
69090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Descriptor to the child's write end of the pipe to the parent process.
69100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // It is always -1 in the parent process.  The parent keeps its end of the
69110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // pipe in read_fd_.
69120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  int write_fd_;
69130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org};
69140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
69150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Called in the parent process only. Reads the result code of the death
69160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// test child process via a pipe, interprets it to set the outcome_
69170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// member, and closes read_fd_.  Outputs diagnostics and terminates in
69180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// case of unexpected codes.
69190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid DeathTestImpl::ReadAndInterpretStatusByte() {
69200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  char flag;
69210d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  int bytes_read;
69220d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
69230d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // The read() here blocks until data is available (signifying the
69240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // failure of the death test) or until the pipe is closed (signifying
69250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // its success), so it's okay to call this in the parent before
69260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // the child process has exited.
69270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  do {
69280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    bytes_read = posix::Read(read_fd(), &flag, 1);
69290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  } while (bytes_read == -1 && errno == EINTR);
69300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
69310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (bytes_read == 0) {
69320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    set_outcome(DIED);
69330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  } else if (bytes_read == 1) {
69340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    switch (flag) {
69350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      case kDeathTestReturned:
69360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        set_outcome(RETURNED);
69370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        break;
69380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      case kDeathTestThrew:
69390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        set_outcome(THREW);
69400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        break;
69410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      case kDeathTestLived:
69420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        set_outcome(LIVED);
69430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        break;
69440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      case kDeathTestInternalError:
69450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        FailFromInternalError(read_fd());  // Does not return.
69460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        break;
69470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      default:
69480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        GTEST_LOG_(FATAL) << "Death test child process reported "
69490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                          << "unexpected status byte ("
69500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                          << static_cast<unsigned int>(flag) << ")";
69510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    }
69520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  } else {
69530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    GTEST_LOG_(FATAL) << "Read from death test child process failed: "
69540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                      << GetLastErrnoDescription();
69550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
69560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Close(read_fd()));
69570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  set_read_fd(-1);
69580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
69590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
69600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Signals that the death test code which should have exited, didn't.
69610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Should be called only in a death test child process.
69620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Writes a status byte to the child's status file descriptor, then
69630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// calls _exit(1).
69640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid DeathTestImpl::Abort(AbortReason reason) {
69650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // The parent process considers the death test to be a failure if
69660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // it finds any data in our pipe.  So, here we write a single flag byte
69670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // to the pipe, then exit.
69680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const char status_ch =
69690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      reason == TEST_DID_NOT_DIE ? kDeathTestLived :
69700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      reason == TEST_THREW_EXCEPTION ? kDeathTestThrew : kDeathTestReturned;
69710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
69720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Write(write_fd(), &status_ch, 1));
69730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // We are leaking the descriptor here because on some platforms (i.e.,
69740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // when built as Windows DLL), destructors of global objects will still
69750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // run after calling _exit(). On such systems, write_fd_ will be
69760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // indirectly closed from the destructor of UnitTestImpl, causing double
69770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // close if it is also closed here. On debug configurations, double close
69780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // may assert. As there are no in-process buffers to flush here, we are
69790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // relying on the OS to close the descriptor after the process terminates
69800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // when the destructors are not run.
69810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  _exit(1);  // Exits w/o any normal exit hooks (we were supposed to crash)
69820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
69830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
69840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Returns an indented copy of stderr output for a death test.
69850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// This makes distinguishing death test output lines from regular log lines
69860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// much easier.
69870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstatic ::std::string FormatDeathTestOutput(const ::std::string& output) {
69880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  ::std::string ret;
69890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  for (size_t at = 0; ; ) {
69900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const size_t line_end = output.find('\n', at);
69910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    ret += "[  DEATH   ] ";
69920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    if (line_end == ::std::string::npos) {
69930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      ret += output.substr(at);
69940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      break;
69950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    }
69960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    ret += output.substr(at, line_end + 1 - at);
69970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    at = line_end + 1;
69980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
69990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return ret;
70000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
70010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
70020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Assesses the success or failure of a death test, using both private
70030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// members which have previously been set, and one argument:
70040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
70050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Private data members:
70060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//   outcome:  An enumeration describing how the death test
70070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//             concluded: DIED, LIVED, THREW, or RETURNED.  The death test
70080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//             fails in the latter three cases.
70090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//   status:   The exit status of the child process. On *nix, it is in the
70100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//             in the format specified by wait(2). On Windows, this is the
70110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//             value supplied to the ExitProcess() API or a numeric code
70120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//             of the exception that terminated the program.
70130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//   regex:    A regular expression object to be applied to
70140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//             the test's captured standard error output; the death test
70150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//             fails if it does not match.
70160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
70170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Argument:
70180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//   status_ok: true if exit_status is acceptable in the context of
70190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//              this particular death test, which fails if it is false
70200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
70210d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Returns true iff all of the above conditions are met.  Otherwise, the
70220d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// first failing condition, in the order given above, is the one that is
70230d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// reported. Also sets the last death test message string.
70240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgbool DeathTestImpl::Passed(bool status_ok) {
70250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (!spawned())
70260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return false;
70270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
70280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const std::string error_message = GetCapturedStderr();
70290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
70300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  bool success = false;
70310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  Message buffer;
70320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
70330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  buffer << "Death test: " << statement() << "\n";
70340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  switch (outcome()) {
70350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    case LIVED:
70360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      buffer << "    Result: failed to die.\n"
70370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org             << " Error msg:\n" << FormatDeathTestOutput(error_message);
70380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      break;
70390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    case THREW:
70400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      buffer << "    Result: threw an exception.\n"
70410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org             << " Error msg:\n" << FormatDeathTestOutput(error_message);
70420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      break;
70430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    case RETURNED:
70440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      buffer << "    Result: illegal return in test statement.\n"
70450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org             << " Error msg:\n" << FormatDeathTestOutput(error_message);
70460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      break;
70470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    case DIED:
70480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      if (status_ok) {
70490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        const bool matched = RE::PartialMatch(error_message.c_str(), *regex());
70500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        if (matched) {
70510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          success = true;
70520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        } else {
70530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          buffer << "    Result: died but not with expected error.\n"
70540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                 << "  Expected: " << regex()->pattern() << "\n"
70550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                 << "Actual msg:\n" << FormatDeathTestOutput(error_message);
70560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        }
70570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      } else {
70580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        buffer << "    Result: died but not with expected exit code:\n"
70590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org               << "            " << ExitSummary(status()) << "\n"
70600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org               << "Actual msg:\n" << FormatDeathTestOutput(error_message);
70610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      }
70620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      break;
70630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    case IN_PROGRESS:
70640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    default:
70650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      GTEST_LOG_(FATAL)
70660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          << "DeathTest::Passed somehow called before conclusion of test";
70670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
70680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
70690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  DeathTest::set_last_death_test_message(buffer.GetString());
70700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return success;
70710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
70720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
70730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# if GTEST_OS_WINDOWS
70740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// WindowsDeathTest implements death tests on Windows. Due to the
70750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// specifics of starting new processes on Windows, death tests there are
70760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// always threadsafe, and Google Test considers the
70770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// --gtest_death_test_style=fast setting to be equivalent to
70780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// --gtest_death_test_style=threadsafe there.
70790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
70800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// A few implementation notes:  Like the Linux version, the Windows
70810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// implementation uses pipes for child-to-parent communication. But due to
70820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// the specifics of pipes on Windows, some extra steps are required:
70830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
70840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// 1. The parent creates a communication pipe and stores handles to both
70850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//    ends of it.
70860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// 2. The parent starts the child and provides it with the information
70870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//    necessary to acquire the handle to the write end of the pipe.
70880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// 3. The child acquires the write end of the pipe and signals the parent
70890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//    using a Windows event.
70900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// 4. Now the parent can release the write end of the pipe on its side. If
70910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//    this is done before step 3, the object's reference count goes down to
70920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//    0 and it is destroyed, preventing the child from acquiring it. The
70930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//    parent now has to release it, or read operations on the read end of
70940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//    the pipe will not return when the child terminates.
70950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// 5. The parent reads child's output through the pipe (outcome code and
70960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//    any possible error messages) from the pipe, and its stderr and then
70970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//    determines whether to fail the test.
70980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
70990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Note: to distinguish Win32 API calls from the local method and function
71000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// calls, the former are explicitly resolved in the global namespace.
71010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
71020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgclass WindowsDeathTest : public DeathTestImpl {
71030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org public:
71040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  WindowsDeathTest(const char* a_statement,
71050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                   const RE* a_regex,
71060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                   const char* file,
71070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                   int line)
71080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      : DeathTestImpl(a_statement, a_regex), file_(file), line_(line) {}
71090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
71100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // All of these virtual functions are inherited from DeathTest.
71110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  virtual int Wait();
71120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  virtual TestRole AssumeRole();
71130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
71140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org private:
71150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // The name of the file in which the death test is located.
71160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const char* const file_;
71170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // The line number on which the death test is located.
71180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const int line_;
71190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Handle to the write end of the pipe to the child process.
71200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  AutoHandle write_handle_;
71210d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Child process handle.
71220d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  AutoHandle child_handle_;
71230d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Event the child process uses to signal the parent that it has
71240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // acquired the handle to the write end of the pipe. After seeing this
71250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // event the parent can release its own handles to make sure its
71260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // ReadFile() calls return when the child terminates.
71270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  AutoHandle event_handle_;
71280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org};
71290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
71300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Waits for the child in a death test to exit, returning its exit
71310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// status, or 0 if no child process exists.  As a side effect, sets the
71320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// outcome data member.
71330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgint WindowsDeathTest::Wait() {
71340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (!spawned())
71350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return 0;
71360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
71370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Wait until the child either signals that it has acquired the write end
71380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // of the pipe or it dies.
71390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const HANDLE wait_handles[2] = { child_handle_.Get(), event_handle_.Get() };
71400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  switch (::WaitForMultipleObjects(2,
71410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                   wait_handles,
71420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                   FALSE,  // Waits for any of the handles.
71430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                   INFINITE)) {
71440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    case WAIT_OBJECT_0:
71450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    case WAIT_OBJECT_0 + 1:
71460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      break;
71470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    default:
71480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      GTEST_DEATH_TEST_CHECK_(false);  // Should not get here.
71490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
71500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
71510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // The child has acquired the write end of the pipe or exited.
71520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // We release the handle on our side and continue.
71530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  write_handle_.Reset();
71540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  event_handle_.Reset();
71550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
71560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  ReadAndInterpretStatusByte();
71570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
71580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Waits for the child process to exit if it haven't already. This
71590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // returns immediately if the child has already exited, regardless of
71600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // whether previous calls to WaitForMultipleObjects synchronized on this
71610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // handle or not.
71620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  GTEST_DEATH_TEST_CHECK_(
71630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      WAIT_OBJECT_0 == ::WaitForSingleObject(child_handle_.Get(),
71640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                             INFINITE));
71650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  DWORD status_code;
71660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  GTEST_DEATH_TEST_CHECK_(
71670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      ::GetExitCodeProcess(child_handle_.Get(), &status_code) != FALSE);
71680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  child_handle_.Reset();
71690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  set_status(static_cast<int>(status_code));
71700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return status();
71710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
71720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
71730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// The AssumeRole process for a Windows death test.  It creates a child
71740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// process with the same executable as the current process to run the
71750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// death test.  The child process is given the --gtest_filter and
71760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// --gtest_internal_run_death_test flags such that it knows to run the
71770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// current death test only.
71780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgDeathTest::TestRole WindowsDeathTest::AssumeRole() {
71790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const UnitTestImpl* const impl = GetUnitTestImpl();
71800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const InternalRunDeathTestFlag* const flag =
71810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      impl->internal_run_death_test_flag();
71820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const TestInfo* const info = impl->current_test_info();
71830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const int death_test_index = info->result()->death_test_count();
71840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
71850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (flag != NULL) {
71860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // ParseInternalRunDeathTestFlag() has performed all the necessary
71870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // processing.
71880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    set_write_fd(flag->write_fd());
71890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return EXECUTE_TEST;
71900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
71910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
71920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // WindowsDeathTest uses an anonymous pipe to communicate results of
71930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // a death test.
71940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  SECURITY_ATTRIBUTES handles_are_inheritable = {
71950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    sizeof(SECURITY_ATTRIBUTES), NULL, TRUE };
71960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  HANDLE read_handle, write_handle;
71970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  GTEST_DEATH_TEST_CHECK_(
71980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      ::CreatePipe(&read_handle, &write_handle, &handles_are_inheritable,
71990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                   0)  // Default buffer size.
72000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      != FALSE);
72010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  set_read_fd(::_open_osfhandle(reinterpret_cast<intptr_t>(read_handle),
72020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                O_RDONLY));
72030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  write_handle_.Reset(write_handle);
72040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  event_handle_.Reset(::CreateEvent(
72050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      &handles_are_inheritable,
72060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      TRUE,    // The event will automatically reset to non-signaled state.
72070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      FALSE,   // The initial state is non-signalled.
72080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      NULL));  // The even is unnamed.
72090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  GTEST_DEATH_TEST_CHECK_(event_handle_.Get() != NULL);
72100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const std::string filter_flag =
72110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      std::string("--") + GTEST_FLAG_PREFIX_ + kFilterFlag + "=" +
72120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      info->test_case_name() + "." + info->name();
72130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const std::string internal_flag =
72140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      std::string("--") + GTEST_FLAG_PREFIX_ + kInternalRunDeathTestFlag +
72150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      "=" + file_ + "|" + StreamableToString(line_) + "|" +
72160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      StreamableToString(death_test_index) + "|" +
72170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      StreamableToString(static_cast<unsigned int>(::GetCurrentProcessId())) +
72180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      // size_t has the same width as pointers on both 32-bit and 64-bit
72190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      // Windows platforms.
72200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      // See http://msdn.microsoft.com/en-us/library/tcxf1dw6.aspx.
72210d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      "|" + StreamableToString(reinterpret_cast<size_t>(write_handle)) +
72220d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      "|" + StreamableToString(reinterpret_cast<size_t>(event_handle_.Get()));
72230d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
72240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  char executable_path[_MAX_PATH + 1];  // NOLINT
72250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  GTEST_DEATH_TEST_CHECK_(
72260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      _MAX_PATH + 1 != ::GetModuleFileNameA(NULL,
72270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                            executable_path,
72280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                            _MAX_PATH));
72290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
72300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  std::string command_line =
72310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      std::string(::GetCommandLineA()) + " " + filter_flag + " \"" +
72320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      internal_flag + "\"";
72330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
72340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  DeathTest::set_last_death_test_message("");
72350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
72360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  CaptureStderr();
72370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Flush the log buffers since the log streams are shared with the child.
72380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  FlushInfoLog();
72390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
72400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // The child process will share the standard handles with the parent.
72410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  STARTUPINFOA startup_info;
72420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  memset(&startup_info, 0, sizeof(STARTUPINFO));
72430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  startup_info.dwFlags = STARTF_USESTDHANDLES;
72440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  startup_info.hStdInput = ::GetStdHandle(STD_INPUT_HANDLE);
72450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  startup_info.hStdOutput = ::GetStdHandle(STD_OUTPUT_HANDLE);
72460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  startup_info.hStdError = ::GetStdHandle(STD_ERROR_HANDLE);
72470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
72480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  PROCESS_INFORMATION process_info;
72490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  GTEST_DEATH_TEST_CHECK_(::CreateProcessA(
72500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      executable_path,
72510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      const_cast<char*>(command_line.c_str()),
72520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      NULL,   // Retuned process handle is not inheritable.
72530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      NULL,   // Retuned thread handle is not inheritable.
72540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      TRUE,   // Child inherits all inheritable handles (for write_handle_).
72550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      0x0,    // Default creation flags.
72560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      NULL,   // Inherit the parent's environment.
72570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      UnitTest::GetInstance()->original_working_dir(),
72580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      &startup_info,
72590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      &process_info) != FALSE);
72600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  child_handle_.Reset(process_info.hProcess);
72610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  ::CloseHandle(process_info.hThread);
72620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  set_spawned(true);
72630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return OVERSEE_TEST;
72640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
72650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# else  // We are not on Windows.
72660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
72670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// ForkingDeathTest provides implementations for most of the abstract
72680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// methods of the DeathTest interface.  Only the AssumeRole method is
72690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// left undefined.
72700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgclass ForkingDeathTest : public DeathTestImpl {
72710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org public:
72720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  ForkingDeathTest(const char* statement, const RE* regex);
72730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
72740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // All of these virtual functions are inherited from DeathTest.
72750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  virtual int Wait();
72760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
72770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org protected:
72780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  void set_child_pid(pid_t child_pid) { child_pid_ = child_pid; }
72790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
72800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org private:
72810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // PID of child process during death test; 0 in the child process itself.
72820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  pid_t child_pid_;
72830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org};
72840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
72850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Constructs a ForkingDeathTest.
72860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgForkingDeathTest::ForkingDeathTest(const char* a_statement, const RE* a_regex)
72870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    : DeathTestImpl(a_statement, a_regex),
72880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      child_pid_(-1) {}
72890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
72900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Waits for the child in a death test to exit, returning its exit
72910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// status, or 0 if no child process exists.  As a side effect, sets the
72920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// outcome data member.
72930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgint ForkingDeathTest::Wait() {
72940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (!spawned())
72950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return 0;
72960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
72970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  ReadAndInterpretStatusByte();
72980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
72990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  int status_value;
73000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  GTEST_DEATH_TEST_CHECK_SYSCALL_(waitpid(child_pid_, &status_value, 0));
73010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  set_status(status_value);
73020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return status_value;
73030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
73040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
73050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// A concrete death test class that forks, then immediately runs the test
73060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// in the child process.
73070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgclass NoExecDeathTest : public ForkingDeathTest {
73080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org public:
73090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  NoExecDeathTest(const char* a_statement, const RE* a_regex) :
73100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      ForkingDeathTest(a_statement, a_regex) { }
73110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  virtual TestRole AssumeRole();
73120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org};
73130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
73140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// The AssumeRole process for a fork-and-run death test.  It implements a
73150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// straightforward fork, with a simple pipe to transmit the status byte.
73160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgDeathTest::TestRole NoExecDeathTest::AssumeRole() {
73170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const size_t thread_count = GetThreadCount();
73180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (thread_count != 1) {
73190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    GTEST_LOG_(WARNING) << DeathTestThreadWarning(thread_count);
73200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
73210d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
73220d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  int pipe_fd[2];
73230d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  GTEST_DEATH_TEST_CHECK_(pipe(pipe_fd) != -1);
73240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
73250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  DeathTest::set_last_death_test_message("");
73260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  CaptureStderr();
73270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // When we fork the process below, the log file buffers are copied, but the
73280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // file descriptors are shared.  We flush all log files here so that closing
73290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // the file descriptors in the child process doesn't throw off the
73300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // synchronization between descriptors and buffers in the parent process.
73310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // This is as close to the fork as possible to avoid a race condition in case
73320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // there are multiple threads running before the death test, and another
73330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // thread writes to the log file.
73340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  FlushInfoLog();
73350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
73360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const pid_t child_pid = fork();
73370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  GTEST_DEATH_TEST_CHECK_(child_pid != -1);
73380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  set_child_pid(child_pid);
73390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (child_pid == 0) {
73400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[0]));
73410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    set_write_fd(pipe_fd[1]);
73420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // Redirects all logging to stderr in the child process to prevent
73430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // concurrent writes to the log files.  We capture stderr in the parent
73440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // process and append the child process' output to a log.
73450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    LogToStderr();
73460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // Event forwarding to the listeners of event listener API mush be shut
73470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // down in death test subprocesses.
73480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    GetUnitTestImpl()->listeners()->SuppressEventForwarding();
73490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    g_in_fast_death_test_child = true;
73500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return EXECUTE_TEST;
73510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  } else {
73520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1]));
73530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    set_read_fd(pipe_fd[0]);
73540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    set_spawned(true);
73550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return OVERSEE_TEST;
73560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
73570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
73580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
73590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// A concrete death test class that forks and re-executes the main
73600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// program from the beginning, with command-line flags set that cause
73610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// only this specific death test to be run.
73620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgclass ExecDeathTest : public ForkingDeathTest {
73630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org public:
73640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  ExecDeathTest(const char* a_statement, const RE* a_regex,
73650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                const char* file, int line) :
73660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      ForkingDeathTest(a_statement, a_regex), file_(file), line_(line) { }
73670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  virtual TestRole AssumeRole();
73680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org private:
73690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  static ::std::vector<testing::internal::string>
73700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  GetArgvsForDeathTestChildProcess() {
73710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    ::std::vector<testing::internal::string> args = GetInjectableArgvs();
73720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return args;
73730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
73740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // The name of the file in which the death test is located.
73750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const char* const file_;
73760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // The line number on which the death test is located.
73770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const int line_;
73780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org};
73790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
73800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Utility class for accumulating command-line arguments.
73810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgclass Arguments {
73820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org public:
73830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  Arguments() {
73840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    args_.push_back(NULL);
73850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
73860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
73870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  ~Arguments() {
73880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    for (std::vector<char*>::iterator i = args_.begin(); i != args_.end();
73890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org         ++i) {
73900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      free(*i);
73910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    }
73920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
73930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  void AddArgument(const char* argument) {
73940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    args_.insert(args_.end() - 1, posix::StrDup(argument));
73950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
73960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
73970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  template <typename Str>
73980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  void AddArguments(const ::std::vector<Str>& arguments) {
73990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    for (typename ::std::vector<Str>::const_iterator i = arguments.begin();
74000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org         i != arguments.end();
74010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org         ++i) {
74020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      args_.insert(args_.end() - 1, posix::StrDup(i->c_str()));
74030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    }
74040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
74050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  char* const* Argv() {
74060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return &args_[0];
74070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
74080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
74090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org private:
74100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  std::vector<char*> args_;
74110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org};
74120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
74130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// A struct that encompasses the arguments to the child process of a
74140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// threadsafe-style death test process.
74150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstruct ExecDeathTestArgs {
74160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  char* const* argv;  // Command-line arguments for the child's call to exec
74170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  int close_fd;       // File descriptor to close; the read end of a pipe
74180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org};
74190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
74200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#  if GTEST_OS_MAC
74210d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orginline char** GetEnviron() {
74220d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // When Google Test is built as a framework on MacOS X, the environ variable
74230d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // is unavailable. Apple's documentation (man environ) recommends using
74240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // _NSGetEnviron() instead.
74250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return *_NSGetEnviron();
74260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
74270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#  else
74280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Some POSIX platforms expect you to declare environ. extern "C" makes
74290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// it reside in the global namespace.
74300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgextern "C" char** environ;
74310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orginline char** GetEnviron() { return environ; }
74320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#  endif  // GTEST_OS_MAC
74330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
74340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#  if !GTEST_OS_QNX
74350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// The main function for a threadsafe-style death test child process.
74360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// This function is called in a clone()-ed process and thus must avoid
74370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// any potentially unsafe operations like malloc or libc functions.
74380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstatic int ExecDeathTestChildMain(void* child_arg) {
74390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  ExecDeathTestArgs* const args = static_cast<ExecDeathTestArgs*>(child_arg);
74400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  GTEST_DEATH_TEST_CHECK_SYSCALL_(close(args->close_fd));
74410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
74420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // We need to execute the test program in the same environment where
74430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // it was originally invoked.  Therefore we change to the original
74440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // working directory first.
74450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const char* const original_dir =
74460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      UnitTest::GetInstance()->original_working_dir();
74470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // We can safely call chdir() as it's a direct system call.
74480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (chdir(original_dir) != 0) {
74490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    DeathTestAbort(std::string("chdir(\"") + original_dir + "\") failed: " +
74500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                   GetLastErrnoDescription());
74510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return EXIT_FAILURE;
74520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
74530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
74540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // We can safely call execve() as it's a direct system call.  We
74550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // cannot use execvp() as it's a libc function and thus potentially
74560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // unsafe.  Since execve() doesn't search the PATH, the user must
74570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // invoke the test program via a valid path that contains at least
74580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // one path separator.
74590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  execve(args->argv[0], args->argv, GetEnviron());
74600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  DeathTestAbort(std::string("execve(") + args->argv[0] + ", ...) in " +
74610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                 original_dir + " failed: " +
74620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                 GetLastErrnoDescription());
74630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return EXIT_FAILURE;
74640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
74650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#  endif  // !GTEST_OS_QNX
74660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
74670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Two utility routines that together determine the direction the stack
74680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// grows.
74690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// This could be accomplished more elegantly by a single recursive
74700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// function, but we want to guard against the unlikely possibility of
74710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// a smart compiler optimizing the recursion away.
74720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
74730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// GTEST_NO_INLINE_ is required to prevent GCC 4.6 from inlining
74740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// StackLowerThanAddress into StackGrowsDown, which then doesn't give
74750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// correct answer.
74760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid StackLowerThanAddress(const void* ptr, bool* result) GTEST_NO_INLINE_;
74770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid StackLowerThanAddress(const void* ptr, bool* result) {
74780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  int dummy;
74790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  *result = (&dummy < ptr);
74800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
74810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
74820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgbool StackGrowsDown() {
74830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  int dummy;
74840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  bool result;
74850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  StackLowerThanAddress(&dummy, &result);
74860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return result;
74870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
74880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
74890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Spawns a child process with the same executable as the current process in
74900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// a thread-safe manner and instructs it to run the death test.  The
74910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// implementation uses fork(2) + exec.  On systems where clone(2) is
74920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// available, it is used instead, being slightly more thread-safe.  On QNX,
74930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// fork supports only single-threaded environments, so this function uses
74940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// spawn(2) there instead.  The function dies with an error message if
74950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// anything goes wrong.
74960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstatic pid_t ExecDeathTestSpawnChild(char* const* argv, int close_fd) {
74970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  ExecDeathTestArgs args = { argv, close_fd };
74980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  pid_t child_pid = -1;
74990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
75000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#  if GTEST_OS_QNX
75010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Obtains the current directory and sets it to be closed in the child
75020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // process.
75030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const int cwd_fd = open(".", O_RDONLY);
75040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  GTEST_DEATH_TEST_CHECK_(cwd_fd != -1);
75050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  GTEST_DEATH_TEST_CHECK_SYSCALL_(fcntl(cwd_fd, F_SETFD, FD_CLOEXEC));
75060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // We need to execute the test program in the same environment where
75070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // it was originally invoked.  Therefore we change to the original
75080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // working directory first.
75090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const char* const original_dir =
75100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      UnitTest::GetInstance()->original_working_dir();
75110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // We can safely call chdir() as it's a direct system call.
75120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (chdir(original_dir) != 0) {
75130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    DeathTestAbort(std::string("chdir(\"") + original_dir + "\") failed: " +
75140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                   GetLastErrnoDescription());
75150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return EXIT_FAILURE;
75160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
75170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
75180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  int fd_flags;
75190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Set close_fd to be closed after spawn.
75200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  GTEST_DEATH_TEST_CHECK_SYSCALL_(fd_flags = fcntl(close_fd, F_GETFD));
75210d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  GTEST_DEATH_TEST_CHECK_SYSCALL_(fcntl(close_fd, F_SETFD,
75220d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                        fd_flags | FD_CLOEXEC));
75230d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  struct inheritance inherit = {0};
75240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // spawn is a system call.
75250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  child_pid = spawn(args.argv[0], 0, NULL, &inherit, args.argv, GetEnviron());
75260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Restores the current working directory.
75270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  GTEST_DEATH_TEST_CHECK_(fchdir(cwd_fd) != -1);
75280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  GTEST_DEATH_TEST_CHECK_SYSCALL_(close(cwd_fd));
75290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
75300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#  else   // GTEST_OS_QNX
75310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#   if GTEST_OS_LINUX
75320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // When a SIGPROF signal is received while fork() or clone() are executing,
75330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // the process may hang. To avoid this, we ignore SIGPROF here and re-enable
75340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // it after the call to fork()/clone() is complete.
75350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  struct sigaction saved_sigprof_action;
75360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  struct sigaction ignore_sigprof_action;
75370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  memset(&ignore_sigprof_action, 0, sizeof(ignore_sigprof_action));
75380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  sigemptyset(&ignore_sigprof_action.sa_mask);
75390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  ignore_sigprof_action.sa_handler = SIG_IGN;
75400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  GTEST_DEATH_TEST_CHECK_SYSCALL_(sigaction(
75410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      SIGPROF, &ignore_sigprof_action, &saved_sigprof_action));
75420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#   endif  // GTEST_OS_LINUX
75430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
75440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#   if GTEST_HAS_CLONE
75450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const bool use_fork = GTEST_FLAG(death_test_use_fork);
75460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
75470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (!use_fork) {
75480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    static const bool stack_grows_down = StackGrowsDown();
75490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const size_t stack_size = getpagesize();
75500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // MMAP_ANONYMOUS is not defined on Mac, so we use MAP_ANON instead.
75510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    void* const stack = mmap(NULL, stack_size, PROT_READ | PROT_WRITE,
75520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                             MAP_ANON | MAP_PRIVATE, -1, 0);
75530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    GTEST_DEATH_TEST_CHECK_(stack != MAP_FAILED);
75540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
75550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // Maximum stack alignment in bytes:  For a downward-growing stack, this
75560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // amount is subtracted from size of the stack space to get an address
75570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // that is within the stack space and is aligned on all systems we care
75580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // about.  As far as I know there is no ABI with stack alignment greater
75590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // than 64.  We assume stack and stack_size already have alignment of
75600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // kMaxStackAlignment.
75610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const size_t kMaxStackAlignment = 64;
75620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    void* const stack_top =
75630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        static_cast<char*>(stack) +
75640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org            (stack_grows_down ? stack_size - kMaxStackAlignment : 0);
75650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    GTEST_DEATH_TEST_CHECK_(stack_size > kMaxStackAlignment &&
75660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        reinterpret_cast<intptr_t>(stack_top) % kMaxStackAlignment == 0);
75670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
75680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    child_pid = clone(&ExecDeathTestChildMain, stack_top, SIGCHLD, &args);
75690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
75700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    GTEST_DEATH_TEST_CHECK_(munmap(stack, stack_size) != -1);
75710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
75720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#   else
75730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const bool use_fork = true;
75740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#   endif  // GTEST_HAS_CLONE
75750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
75760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (use_fork && (child_pid = fork()) == 0) {
75770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      ExecDeathTestChildMain(&args);
75780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      _exit(0);
75790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
75800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#  endif  // GTEST_OS_QNX
75810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#  if GTEST_OS_LINUX
75820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  GTEST_DEATH_TEST_CHECK_SYSCALL_(
75830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      sigaction(SIGPROF, &saved_sigprof_action, NULL));
75840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#  endif  // GTEST_OS_LINUX
75850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
75860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  GTEST_DEATH_TEST_CHECK_(child_pid != -1);
75870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return child_pid;
75880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
75890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
75900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// The AssumeRole process for a fork-and-exec death test.  It re-executes the
75910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// main program from the beginning, setting the --gtest_filter
75920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// and --gtest_internal_run_death_test flags to cause only the current
75930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// death test to be re-run.
75940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgDeathTest::TestRole ExecDeathTest::AssumeRole() {
75950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const UnitTestImpl* const impl = GetUnitTestImpl();
75960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const InternalRunDeathTestFlag* const flag =
75970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      impl->internal_run_death_test_flag();
75980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const TestInfo* const info = impl->current_test_info();
75990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const int death_test_index = info->result()->death_test_count();
76000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
76010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (flag != NULL) {
76020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    set_write_fd(flag->write_fd());
76030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return EXECUTE_TEST;
76040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
76050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
76060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  int pipe_fd[2];
76070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  GTEST_DEATH_TEST_CHECK_(pipe(pipe_fd) != -1);
76080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Clear the close-on-exec flag on the write end of the pipe, lest
76090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // it be closed when the child process does an exec:
76100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  GTEST_DEATH_TEST_CHECK_(fcntl(pipe_fd[1], F_SETFD, 0) != -1);
76110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
76120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const std::string filter_flag =
76130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      std::string("--") + GTEST_FLAG_PREFIX_ + kFilterFlag + "="
76140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      + info->test_case_name() + "." + info->name();
76150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const std::string internal_flag =
76160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      std::string("--") + GTEST_FLAG_PREFIX_ + kInternalRunDeathTestFlag + "="
76170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      + file_ + "|" + StreamableToString(line_) + "|"
76180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      + StreamableToString(death_test_index) + "|"
76190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      + StreamableToString(pipe_fd[1]);
76200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  Arguments args;
76210d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  args.AddArguments(GetArgvsForDeathTestChildProcess());
76220d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  args.AddArgument(filter_flag.c_str());
76230d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  args.AddArgument(internal_flag.c_str());
76240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
76250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  DeathTest::set_last_death_test_message("");
76260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
76270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  CaptureStderr();
76280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // See the comment in NoExecDeathTest::AssumeRole for why the next line
76290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // is necessary.
76300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  FlushInfoLog();
76310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
76320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const pid_t child_pid = ExecDeathTestSpawnChild(args.Argv(), pipe_fd[0]);
76330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1]));
76340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  set_child_pid(child_pid);
76350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  set_read_fd(pipe_fd[0]);
76360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  set_spawned(true);
76370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return OVERSEE_TEST;
76380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
76390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
76400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# endif  // !GTEST_OS_WINDOWS
76410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
76420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Creates a concrete DeathTest-derived class that depends on the
76430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// --gtest_death_test_style flag, and sets the pointer pointed to
76440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// by the "test" argument to its address.  If the test should be
76450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// skipped, sets that pointer to NULL.  Returns true, unless the
76460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// flag is set to an invalid value.
76470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgbool DefaultDeathTestFactory::Create(const char* statement, const RE* regex,
76480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                     const char* file, int line,
76490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                     DeathTest** test) {
76500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  UnitTestImpl* const impl = GetUnitTestImpl();
76510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const InternalRunDeathTestFlag* const flag =
76520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      impl->internal_run_death_test_flag();
76530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const int death_test_index = impl->current_test_info()
76540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      ->increment_death_test_count();
76550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
76560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (flag != NULL) {
76570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    if (death_test_index > flag->index()) {
76580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      DeathTest::set_last_death_test_message(
76590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          "Death test count (" + StreamableToString(death_test_index)
76600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          + ") somehow exceeded expected maximum ("
76610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          + StreamableToString(flag->index()) + ")");
76620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      return false;
76630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    }
76640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
76650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    if (!(flag->file() == file && flag->line() == line &&
76660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          flag->index() == death_test_index)) {
76670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      *test = NULL;
76680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      return true;
76690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    }
76700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
76710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
76720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# if GTEST_OS_WINDOWS
76730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
76740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (GTEST_FLAG(death_test_style) == "threadsafe" ||
76750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      GTEST_FLAG(death_test_style) == "fast") {
76760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    *test = new WindowsDeathTest(statement, regex, file, line);
76770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
76780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
76790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# else
76800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
76810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (GTEST_FLAG(death_test_style) == "threadsafe") {
76820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    *test = new ExecDeathTest(statement, regex, file, line);
76830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  } else if (GTEST_FLAG(death_test_style) == "fast") {
76840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    *test = new NoExecDeathTest(statement, regex);
76850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
76860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
76870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# endif  // GTEST_OS_WINDOWS
76880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
76890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  else {  // NOLINT - this is more readable than unbalanced brackets inside #if.
76900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    DeathTest::set_last_death_test_message(
76910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        "Unknown death test style \"" + GTEST_FLAG(death_test_style)
76920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        + "\" encountered");
76930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return false;
76940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
76950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
76960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return true;
76970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
76980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
76990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Splits a given string on a given delimiter, populating a given
77000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// vector with the fields.  GTEST_HAS_DEATH_TEST implies that we have
77010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// ::std::string, so we can use it here.
77020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstatic void SplitString(const ::std::string& str, char delimiter,
77030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                        ::std::vector< ::std::string>* dest) {
77040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  ::std::vector< ::std::string> parsed;
77050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  ::std::string::size_type pos = 0;
77060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  while (::testing::internal::AlwaysTrue()) {
77070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const ::std::string::size_type colon = str.find(delimiter, pos);
77080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    if (colon == ::std::string::npos) {
77090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      parsed.push_back(str.substr(pos));
77100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      break;
77110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    } else {
77120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      parsed.push_back(str.substr(pos, colon - pos));
77130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      pos = colon + 1;
77140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    }
77150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
77160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  dest->swap(parsed);
77170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
77180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
77190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# if GTEST_OS_WINDOWS
77200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Recreates the pipe and event handles from the provided parameters,
77210d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// signals the event, and returns a file descriptor wrapped around the pipe
77220d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// handle. This function is called in the child process only.
77230d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgint GetStatusFileDescriptor(unsigned int parent_process_id,
77240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                            size_t write_handle_as_size_t,
77250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                            size_t event_handle_as_size_t) {
77260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  AutoHandle parent_process_handle(::OpenProcess(PROCESS_DUP_HANDLE,
77270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                                   FALSE,  // Non-inheritable.
77280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                                   parent_process_id));
77290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (parent_process_handle.Get() == INVALID_HANDLE_VALUE) {
77300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    DeathTestAbort("Unable to open parent process " +
77310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                   StreamableToString(parent_process_id));
77320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
77330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
77340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // TODO(vladl@google.com): Replace the following check with a
77350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // compile-time assertion when available.
77360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  GTEST_CHECK_(sizeof(HANDLE) <= sizeof(size_t));
77370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
77380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const HANDLE write_handle =
77390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      reinterpret_cast<HANDLE>(write_handle_as_size_t);
77400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  HANDLE dup_write_handle;
77410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
77420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // The newly initialized handle is accessible only in in the parent
77430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // process. To obtain one accessible within the child, we need to use
77440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // DuplicateHandle.
77450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (!::DuplicateHandle(parent_process_handle.Get(), write_handle,
77460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                         ::GetCurrentProcess(), &dup_write_handle,
77470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                         0x0,    // Requested privileges ignored since
77480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                 // DUPLICATE_SAME_ACCESS is used.
77490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                         FALSE,  // Request non-inheritable handler.
77500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                         DUPLICATE_SAME_ACCESS)) {
77510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    DeathTestAbort("Unable to duplicate the pipe handle " +
77520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                   StreamableToString(write_handle_as_size_t) +
77530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                   " from the parent process " +
77540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                   StreamableToString(parent_process_id));
77550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
77560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
77570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const HANDLE event_handle = reinterpret_cast<HANDLE>(event_handle_as_size_t);
77580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  HANDLE dup_event_handle;
77590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
77600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (!::DuplicateHandle(parent_process_handle.Get(), event_handle,
77610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                         ::GetCurrentProcess(), &dup_event_handle,
77620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                         0x0,
77630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                         FALSE,
77640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                         DUPLICATE_SAME_ACCESS)) {
77650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    DeathTestAbort("Unable to duplicate the event handle " +
77660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                   StreamableToString(event_handle_as_size_t) +
77670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                   " from the parent process " +
77680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                   StreamableToString(parent_process_id));
77690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
77700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
77710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const int write_fd =
77720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      ::_open_osfhandle(reinterpret_cast<intptr_t>(dup_write_handle), O_APPEND);
77730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (write_fd == -1) {
77740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    DeathTestAbort("Unable to convert pipe handle " +
77750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                   StreamableToString(write_handle_as_size_t) +
77760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                   " to a file descriptor");
77770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
77780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
77790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Signals the parent that the write end of the pipe has been acquired
77800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // so the parent can release its own write end.
77810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  ::SetEvent(dup_event_handle);
77820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
77830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return write_fd;
77840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
77850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# endif  // GTEST_OS_WINDOWS
77860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
77870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Returns a newly created InternalRunDeathTestFlag object with fields
77880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// initialized from the GTEST_FLAG(internal_run_death_test) flag if
77890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// the flag is specified; otherwise returns NULL.
77900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgInternalRunDeathTestFlag* ParseInternalRunDeathTestFlag() {
77910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (GTEST_FLAG(internal_run_death_test) == "") return NULL;
77920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
77930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we
77940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // can use it here.
77950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  int line = -1;
77960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  int index = -1;
77970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  ::std::vector< ::std::string> fields;
77980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  SplitString(GTEST_FLAG(internal_run_death_test).c_str(), '|', &fields);
77990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  int write_fd = -1;
78000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
78010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# if GTEST_OS_WINDOWS
78020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
78030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  unsigned int parent_process_id = 0;
78040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  size_t write_handle_as_size_t = 0;
78050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  size_t event_handle_as_size_t = 0;
78060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
78070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (fields.size() != 6
78080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      || !ParseNaturalNumber(fields[1], &line)
78090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      || !ParseNaturalNumber(fields[2], &index)
78100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      || !ParseNaturalNumber(fields[3], &parent_process_id)
78110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      || !ParseNaturalNumber(fields[4], &write_handle_as_size_t)
78120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      || !ParseNaturalNumber(fields[5], &event_handle_as_size_t)) {
78130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    DeathTestAbort("Bad --gtest_internal_run_death_test flag: " +
78140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                   GTEST_FLAG(internal_run_death_test));
78150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
78160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  write_fd = GetStatusFileDescriptor(parent_process_id,
78170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                     write_handle_as_size_t,
78180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                     event_handle_as_size_t);
78190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# else
78200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
78210d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (fields.size() != 4
78220d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      || !ParseNaturalNumber(fields[1], &line)
78230d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      || !ParseNaturalNumber(fields[2], &index)
78240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      || !ParseNaturalNumber(fields[3], &write_fd)) {
78250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    DeathTestAbort("Bad --gtest_internal_run_death_test flag: "
78260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        + GTEST_FLAG(internal_run_death_test));
78270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
78280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
78290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# endif  // GTEST_OS_WINDOWS
78300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
78310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return new InternalRunDeathTestFlag(fields[0], line, index, write_fd);
78320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
78330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
78340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}  // namespace internal
78350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
78360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#endif  // GTEST_HAS_DEATH_TEST
78370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
78380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}  // namespace testing
78390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Copyright 2008, Google Inc.
78400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// All rights reserved.
78410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
78420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Redistribution and use in source and binary forms, with or without
78430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// modification, are permitted provided that the following conditions are
78440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// met:
78450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
78460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//     * Redistributions of source code must retain the above copyright
78470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// notice, this list of conditions and the following disclaimer.
78480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//     * Redistributions in binary form must reproduce the above
78490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// copyright notice, this list of conditions and the following disclaimer
78500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// in the documentation and/or other materials provided with the
78510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// distribution.
78520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//     * Neither the name of Google Inc. nor the names of its
78530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// contributors may be used to endorse or promote products derived from
78540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// this software without specific prior written permission.
78550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
78560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
78570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
78580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
78590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
78600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
78610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
78620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
78630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
78640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
78650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
78660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
78670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
78680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Authors: keith.ray@gmail.com (Keith Ray)
78690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
78700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
78710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#include <stdlib.h>
78720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
78730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#if GTEST_OS_WINDOWS_MOBILE
78740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# include <windows.h>
78750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#elif GTEST_OS_WINDOWS
78760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# include <direct.h>
78770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# include <io.h>
78780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#elif GTEST_OS_SYMBIAN
78790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Symbian OpenC has PATH_MAX in sys/syslimits.h
78800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# include <sys/syslimits.h>
78810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#else
78820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# include <limits.h>
78830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# include <climits>  // Some Linux distributions define PATH_MAX here.
78840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#endif  // GTEST_OS_WINDOWS_MOBILE
78850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
78860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#if GTEST_OS_WINDOWS
78870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# define GTEST_PATH_MAX_ _MAX_PATH
78880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#elif defined(PATH_MAX)
78890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# define GTEST_PATH_MAX_ PATH_MAX
78900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#elif defined(_XOPEN_PATH_MAX)
78910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# define GTEST_PATH_MAX_ _XOPEN_PATH_MAX
78920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#else
78930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# define GTEST_PATH_MAX_ _POSIX_PATH_MAX
78940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#endif  // GTEST_OS_WINDOWS
78950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
78960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
78970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgnamespace testing {
78980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgnamespace internal {
78990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
79000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#if GTEST_OS_WINDOWS
79010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// On Windows, '\\' is the standard path separator, but many tools and the
79020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Windows API also accept '/' as an alternate path separator. Unless otherwise
79030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// noted, a file path can contain either kind of path separators, or a mixture
79040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// of them.
79050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgconst char kPathSeparator = '\\';
79060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgconst char kAlternatePathSeparator = '/';
79070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgconst char kAlternatePathSeparatorString[] = "/";
79080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# if GTEST_OS_WINDOWS_MOBILE
79090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Windows CE doesn't have a current directory. You should not use
79100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// the current directory in tests on Windows CE, but this at least
79110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// provides a reasonable fallback.
79120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgconst char kCurrentDirectoryString[] = "\\";
79130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Windows CE doesn't define INVALID_FILE_ATTRIBUTES
79140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgconst DWORD kInvalidFileAttributes = 0xffffffff;
79150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# else
79160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgconst char kCurrentDirectoryString[] = ".\\";
79170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# endif  // GTEST_OS_WINDOWS_MOBILE
79180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#else
79190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgconst char kPathSeparator = '/';
79200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgconst char kCurrentDirectoryString[] = "./";
79210d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#endif  // GTEST_OS_WINDOWS
79220d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
79230d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Returns whether the given character is a valid path separator.
79240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstatic bool IsPathSeparator(char c) {
79250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#if GTEST_HAS_ALT_PATH_SEP_
79260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return (c == kPathSeparator) || (c == kAlternatePathSeparator);
79270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#else
79280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return c == kPathSeparator;
79290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#endif
79300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
79310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
79320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Returns the current working directory, or "" if unsuccessful.
79330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgFilePath FilePath::GetCurrentDir() {
79340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#if GTEST_OS_WINDOWS_MOBILE
79350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Windows CE doesn't have a current directory, so we just return
79360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // something reasonable.
79370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return FilePath(kCurrentDirectoryString);
79380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#elif GTEST_OS_WINDOWS
79390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  char cwd[GTEST_PATH_MAX_ + 1] = { '\0' };
79400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return FilePath(_getcwd(cwd, sizeof(cwd)) == NULL ? "" : cwd);
79410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#else
79420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  char cwd[GTEST_PATH_MAX_ + 1] = { '\0' };
79430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return FilePath(getcwd(cwd, sizeof(cwd)) == NULL ? "" : cwd);
79440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#endif  // GTEST_OS_WINDOWS_MOBILE
79450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
79460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
79470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Returns a copy of the FilePath with the case-insensitive extension removed.
79480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Example: FilePath("dir/file.exe").RemoveExtension("EXE") returns
79490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// FilePath("dir/file"). If a case-insensitive extension is not
79500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// found, returns a copy of the original FilePath.
79510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgFilePath FilePath::RemoveExtension(const char* extension) const {
79520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const std::string dot_extension = std::string(".") + extension;
79530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (String::EndsWithCaseInsensitive(pathname_, dot_extension)) {
79540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return FilePath(pathname_.substr(
79550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        0, pathname_.length() - dot_extension.length()));
79560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
79570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return *this;
79580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
79590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
79600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Returns a pointer to the last occurence of a valid path separator in
79610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// the FilePath. On Windows, for example, both '/' and '\' are valid path
79620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// separators. Returns NULL if no path separator was found.
79630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgconst char* FilePath::FindLastPathSeparator() const {
79640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const char* const last_sep = strrchr(c_str(), kPathSeparator);
79650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#if GTEST_HAS_ALT_PATH_SEP_
79660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const char* const last_alt_sep = strrchr(c_str(), kAlternatePathSeparator);
79670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Comparing two pointers of which only one is NULL is undefined.
79680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (last_alt_sep != NULL &&
79690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      (last_sep == NULL || last_alt_sep > last_sep)) {
79700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return last_alt_sep;
79710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
79720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#endif
79730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return last_sep;
79740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
79750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
79760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Returns a copy of the FilePath with the directory part removed.
79770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Example: FilePath("path/to/file").RemoveDirectoryName() returns
79780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// FilePath("file"). If there is no directory part ("just_a_file"), it returns
79790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// the FilePath unmodified. If there is no file part ("just_a_dir/") it
79800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// returns an empty FilePath ("").
79810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// On Windows platform, '\' is the path separator, otherwise it is '/'.
79820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgFilePath FilePath::RemoveDirectoryName() const {
79830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const char* const last_sep = FindLastPathSeparator();
79840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return last_sep ? FilePath(last_sep + 1) : *this;
79850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
79860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
79870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// RemoveFileName returns the directory path with the filename removed.
79880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Example: FilePath("path/to/file").RemoveFileName() returns "path/to/".
79890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// If the FilePath is "a_file" or "/a_file", RemoveFileName returns
79900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// FilePath("./") or, on Windows, FilePath(".\\"). If the filepath does
79910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// not have a file, like "just/a/dir/", it returns the FilePath unmodified.
79920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// On Windows platform, '\' is the path separator, otherwise it is '/'.
79930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgFilePath FilePath::RemoveFileName() const {
79940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const char* const last_sep = FindLastPathSeparator();
79950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  std::string dir;
79960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (last_sep) {
79970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    dir = std::string(c_str(), last_sep + 1 - c_str());
79980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  } else {
79990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    dir = kCurrentDirectoryString;
80000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
80010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return FilePath(dir);
80020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
80030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
80040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Helper functions for naming files in a directory for xml output.
80050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
80060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Given directory = "dir", base_name = "test", number = 0,
80070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// extension = "xml", returns "dir/test.xml". If number is greater
80080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// than zero (e.g., 12), returns "dir/test_12.xml".
80090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// On Windows platform, uses \ as the separator rather than /.
80100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgFilePath FilePath::MakeFileName(const FilePath& directory,
80110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                const FilePath& base_name,
80120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                int number,
80130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                const char* extension) {
80140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  std::string file;
80150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (number == 0) {
80160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    file = base_name.string() + "." + extension;
80170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  } else {
80180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    file = base_name.string() + "_" + StreamableToString(number)
80190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        + "." + extension;
80200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
80210d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return ConcatPaths(directory, FilePath(file));
80220d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
80230d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
80240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Given directory = "dir", relative_path = "test.xml", returns "dir/test.xml".
80250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// On Windows, uses \ as the separator rather than /.
80260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgFilePath FilePath::ConcatPaths(const FilePath& directory,
80270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                               const FilePath& relative_path) {
80280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (directory.IsEmpty())
80290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return relative_path;
80300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const FilePath dir(directory.RemoveTrailingPathSeparator());
80310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return FilePath(dir.string() + kPathSeparator + relative_path.string());
80320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
80330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
80340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Returns true if pathname describes something findable in the file-system,
80350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// either a file, directory, or whatever.
80360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgbool FilePath::FileOrDirectoryExists() const {
80370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#if GTEST_OS_WINDOWS_MOBILE
80380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  LPCWSTR unicode = String::AnsiToUtf16(pathname_.c_str());
80390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const DWORD attributes = GetFileAttributes(unicode);
80400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  delete [] unicode;
80410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return attributes != kInvalidFileAttributes;
80420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#else
80430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  posix::StatStruct file_stat;
80440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return posix::Stat(pathname_.c_str(), &file_stat) == 0;
80450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#endif  // GTEST_OS_WINDOWS_MOBILE
80460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
80470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
80480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Returns true if pathname describes a directory in the file-system
80490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// that exists.
80500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgbool FilePath::DirectoryExists() const {
80510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  bool result = false;
80520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#if GTEST_OS_WINDOWS
80530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Don't strip off trailing separator if path is a root directory on
80540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Windows (like "C:\\").
80550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const FilePath& path(IsRootDirectory() ? *this :
80560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                           RemoveTrailingPathSeparator());
80570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#else
80580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const FilePath& path(*this);
80590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#endif
80600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
80610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#if GTEST_OS_WINDOWS_MOBILE
80620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  LPCWSTR unicode = String::AnsiToUtf16(path.c_str());
80630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const DWORD attributes = GetFileAttributes(unicode);
80640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  delete [] unicode;
80650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if ((attributes != kInvalidFileAttributes) &&
80660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      (attributes & FILE_ATTRIBUTE_DIRECTORY)) {
80670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    result = true;
80680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
80690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#else
80700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  posix::StatStruct file_stat;
80710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  result = posix::Stat(path.c_str(), &file_stat) == 0 &&
80720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      posix::IsDir(file_stat);
80730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#endif  // GTEST_OS_WINDOWS_MOBILE
80740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
80750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return result;
80760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
80770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
80780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Returns true if pathname describes a root directory. (Windows has one
80790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// root directory per disk drive.)
80800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgbool FilePath::IsRootDirectory() const {
80810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#if GTEST_OS_WINDOWS
80820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // TODO(wan@google.com): on Windows a network share like
80830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // \\server\share can be a root directory, although it cannot be the
80840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // current directory.  Handle this properly.
80850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return pathname_.length() == 3 && IsAbsolutePath();
80860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#else
80870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return pathname_.length() == 1 && IsPathSeparator(pathname_.c_str()[0]);
80880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#endif
80890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
80900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
80910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Returns true if pathname describes an absolute path.
80920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgbool FilePath::IsAbsolutePath() const {
80930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const char* const name = pathname_.c_str();
80940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#if GTEST_OS_WINDOWS
80950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return pathname_.length() >= 3 &&
80960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org     ((name[0] >= 'a' && name[0] <= 'z') ||
80970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      (name[0] >= 'A' && name[0] <= 'Z')) &&
80980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org     name[1] == ':' &&
80990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org     IsPathSeparator(name[2]);
81000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#else
81010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return IsPathSeparator(name[0]);
81020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#endif
81030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
81040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
81050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Returns a pathname for a file that does not currently exist. The pathname
81060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// will be directory/base_name.extension or
81070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// directory/base_name_<number>.extension if directory/base_name.extension
81080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// already exists. The number will be incremented until a pathname is found
81090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// that does not already exist.
81100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Examples: 'dir/foo_test.xml' or 'dir/foo_test_1.xml'.
81110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// There could be a race condition if two or more processes are calling this
81120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// function at the same time -- they could both pick the same filename.
81130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgFilePath FilePath::GenerateUniqueFileName(const FilePath& directory,
81140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                          const FilePath& base_name,
81150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                          const char* extension) {
81160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  FilePath full_pathname;
81170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  int number = 0;
81180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  do {
81190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    full_pathname.Set(MakeFileName(directory, base_name, number++, extension));
81200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  } while (full_pathname.FileOrDirectoryExists());
81210d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return full_pathname;
81220d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
81230d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
81240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Returns true if FilePath ends with a path separator, which indicates that
81250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// it is intended to represent a directory. Returns false otherwise.
81260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// This does NOT check that a directory (or file) actually exists.
81270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgbool FilePath::IsDirectory() const {
81280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return !pathname_.empty() &&
81290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org         IsPathSeparator(pathname_.c_str()[pathname_.length() - 1]);
81300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
81310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
81320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Create directories so that path exists. Returns true if successful or if
81330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// the directories already exist; returns false if unable to create directories
81340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// for any reason.
81350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgbool FilePath::CreateDirectoriesRecursively() const {
81360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (!this->IsDirectory()) {
81370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return false;
81380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
81390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
81400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (pathname_.length() == 0 || this->DirectoryExists()) {
81410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return true;
81420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
81430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
81440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const FilePath parent(this->RemoveTrailingPathSeparator().RemoveFileName());
81450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return parent.CreateDirectoriesRecursively() && this->CreateFolder();
81460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
81470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
81480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Create the directory so that path exists. Returns true if successful or
81490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// if the directory already exists; returns false if unable to create the
81500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// directory for any reason, including if the parent directory does not
81510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// exist. Not named "CreateDirectory" because that's a macro on Windows.
81520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgbool FilePath::CreateFolder() const {
81530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#if GTEST_OS_WINDOWS_MOBILE
81540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  FilePath removed_sep(this->RemoveTrailingPathSeparator());
81550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  LPCWSTR unicode = String::AnsiToUtf16(removed_sep.c_str());
81560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  int result = CreateDirectory(unicode, NULL) ? 0 : -1;
81570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  delete [] unicode;
81580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#elif GTEST_OS_WINDOWS
81590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  int result = _mkdir(pathname_.c_str());
81600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#else
81610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  int result = mkdir(pathname_.c_str(), 0777);
81620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#endif  // GTEST_OS_WINDOWS_MOBILE
81630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
81640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (result == -1) {
81650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return this->DirectoryExists();  // An error is OK if the directory exists.
81660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
81670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return true;  // No error.
81680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
81690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
81700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// If input name has a trailing separator character, remove it and return the
81710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// name, otherwise return the name string unmodified.
81720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// On Windows platform, uses \ as the separator, other platforms use /.
81730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgFilePath FilePath::RemoveTrailingPathSeparator() const {
81740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return IsDirectory()
81750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      ? FilePath(pathname_.substr(0, pathname_.length() - 1))
81760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      : *this;
81770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
81780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
81790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Removes any redundant separators that might be in the pathname.
81800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// For example, "bar///foo" becomes "bar/foo". Does not eliminate other
81810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// redundancies that might be in a pathname involving "." or "..".
81820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// TODO(wan@google.com): handle Windows network shares (e.g. \\server\share).
81830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid FilePath::Normalize() {
81840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (pathname_.c_str() == NULL) {
81850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    pathname_ = "";
81860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return;
81870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
81880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const char* src = pathname_.c_str();
81890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  char* const dest = new char[pathname_.length() + 1];
81900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  char* dest_ptr = dest;
81910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  memset(dest_ptr, 0, pathname_.length() + 1);
81920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
81930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  while (*src != '\0') {
81940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    *dest_ptr = *src;
81950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    if (!IsPathSeparator(*src)) {
81960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      src++;
81970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    } else {
81980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#if GTEST_HAS_ALT_PATH_SEP_
81990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      if (*dest_ptr == kAlternatePathSeparator) {
82000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        *dest_ptr = kPathSeparator;
82010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      }
82020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#endif
82030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      while (IsPathSeparator(*src))
82040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        src++;
82050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    }
82060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    dest_ptr++;
82070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
82080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  *dest_ptr = '\0';
82090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  pathname_ = dest;
82100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  delete[] dest;
82110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
82120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
82130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}  // namespace internal
82140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}  // namespace testing
82150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Copyright 2008, Google Inc.
82160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// All rights reserved.
82170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
82180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Redistribution and use in source and binary forms, with or without
82190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// modification, are permitted provided that the following conditions are
82200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// met:
82210d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
82220d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//     * Redistributions of source code must retain the above copyright
82230d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// notice, this list of conditions and the following disclaimer.
82240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//     * Redistributions in binary form must reproduce the above
82250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// copyright notice, this list of conditions and the following disclaimer
82260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// in the documentation and/or other materials provided with the
82270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// distribution.
82280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//     * Neither the name of Google Inc. nor the names of its
82290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// contributors may be used to endorse or promote products derived from
82300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// this software without specific prior written permission.
82310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
82320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
82330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
82340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
82350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
82360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
82370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
82380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
82390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
82400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
82410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
82420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
82430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
82440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Author: wan@google.com (Zhanyong Wan)
82450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
82460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
82470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#include <limits.h>
82480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#include <stdlib.h>
82490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#include <stdio.h>
82500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#include <string.h>
82510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
82520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#if GTEST_OS_WINDOWS_MOBILE
82530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# include <windows.h>  // For TerminateProcess()
82540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#elif GTEST_OS_WINDOWS
82550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# include <io.h>
82560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# include <sys/stat.h>
82570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#else
82580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# include <unistd.h>
82590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#endif  // GTEST_OS_WINDOWS_MOBILE
82600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
82610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#if GTEST_OS_MAC
82620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# include <mach/mach_init.h>
82630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# include <mach/task.h>
82640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# include <mach/vm_map.h>
82650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#endif  // GTEST_OS_MAC
82660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
82670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#if GTEST_OS_QNX
82680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# include <devctl.h>
82690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# include <sys/procfs.h>
82700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#endif  // GTEST_OS_QNX
82710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
82720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
82730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Indicates that this translation unit is part of Google Test's
82740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// implementation.  It must come before gtest-internal-inl.h is
82750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// included, or there will be a compiler error.  This trick is to
82760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// prevent a user from accidentally including gtest-internal-inl.h in
82770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// his code.
82780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#define GTEST_IMPLEMENTATION_ 1
82790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#undef GTEST_IMPLEMENTATION_
82800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
82810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgnamespace testing {
82820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgnamespace internal {
82830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
82840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#if defined(_MSC_VER) || defined(__BORLANDC__)
82850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// MSVC and C++Builder do not provide a definition of STDERR_FILENO.
82860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgconst int kStdOutFileno = 1;
82870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgconst int kStdErrFileno = 2;
82880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#else
82890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgconst int kStdOutFileno = STDOUT_FILENO;
82900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgconst int kStdErrFileno = STDERR_FILENO;
82910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#endif  // _MSC_VER
82920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
82930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#if GTEST_OS_MAC
82940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
82950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Returns the number of threads running in the process, or 0 to indicate that
82960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// we cannot detect it.
82970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgsize_t GetThreadCount() {
82980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const task_t task = mach_task_self();
82990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  mach_msg_type_number_t thread_count;
83000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  thread_act_array_t thread_list;
83010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const kern_return_t status = task_threads(task, &thread_list, &thread_count);
83020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (status == KERN_SUCCESS) {
83030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // task_threads allocates resources in thread_list and we need to free them
83040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // to avoid leaks.
83050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    vm_deallocate(task,
83060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                  reinterpret_cast<vm_address_t>(thread_list),
83070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                  sizeof(thread_t) * thread_count);
83080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return static_cast<size_t>(thread_count);
83090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  } else {
83100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return 0;
83110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
83120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
83130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
83140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#elif GTEST_OS_QNX
83150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
83160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Returns the number of threads running in the process, or 0 to indicate that
83170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// we cannot detect it.
83180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgsize_t GetThreadCount() {
83190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const int fd = open("/proc/self/as", O_RDONLY);
83200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (fd < 0) {
83210d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return 0;
83220d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
83230d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  procfs_info process_info;
83240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const int status =
83250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      devctl(fd, DCMD_PROC_INFO, &process_info, sizeof(process_info), NULL);
83260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  close(fd);
83270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (status == EOK) {
83280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return static_cast<size_t>(process_info.num_threads);
83290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  } else {
83300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return 0;
83310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
83320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
83330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
83340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#else
83350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
83360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgsize_t GetThreadCount() {
83370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // There's no portable way to detect the number of threads, so we just
83380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // return 0 to indicate that we cannot detect it.
83390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return 0;
83400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
83410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
83420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#endif  // GTEST_OS_MAC
83430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
83440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#if GTEST_USES_POSIX_RE
83450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
83460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Implements RE.  Currently only needed for death tests.
83470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
83480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgRE::~RE() {
83490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (is_valid_) {
83500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // regfree'ing an invalid regex might crash because the content
83510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // of the regex is undefined. Since the regex's are essentially
83520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // the same, one cannot be valid (or invalid) without the other
83530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // being so too.
83540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    regfree(&partial_regex_);
83550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    regfree(&full_regex_);
83560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
83570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  free(const_cast<char*>(pattern_));
83580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
83590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
83600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Returns true iff regular expression re matches the entire str.
83610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgbool RE::FullMatch(const char* str, const RE& re) {
83620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (!re.is_valid_) return false;
83630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
83640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  regmatch_t match;
83650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return regexec(&re.full_regex_, str, 1, &match, 0) == 0;
83660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
83670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
83680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Returns true iff regular expression re matches a substring of str
83690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// (including str itself).
83700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgbool RE::PartialMatch(const char* str, const RE& re) {
83710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (!re.is_valid_) return false;
83720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
83730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  regmatch_t match;
83740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return regexec(&re.partial_regex_, str, 1, &match, 0) == 0;
83750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
83760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
83770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Initializes an RE from its string representation.
83780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid RE::Init(const char* regex) {
83790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  pattern_ = posix::StrDup(regex);
83800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
83810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Reserves enough bytes to hold the regular expression used for a
83820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // full match.
83830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const size_t full_regex_len = strlen(regex) + 10;
83840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  char* const full_pattern = new char[full_regex_len];
83850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
83860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  snprintf(full_pattern, full_regex_len, "^(%s)$", regex);
83870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  is_valid_ = regcomp(&full_regex_, full_pattern, REG_EXTENDED) == 0;
83880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // We want to call regcomp(&partial_regex_, ...) even if the
83890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // previous expression returns false.  Otherwise partial_regex_ may
83900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // not be properly initialized can may cause trouble when it's
83910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // freed.
83920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  //
83930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Some implementation of POSIX regex (e.g. on at least some
83940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // versions of Cygwin) doesn't accept the empty string as a valid
83950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // regex.  We change it to an equivalent form "()" to be safe.
83960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (is_valid_) {
83970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const char* const partial_regex = (*regex == '\0') ? "()" : regex;
83980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    is_valid_ = regcomp(&partial_regex_, partial_regex, REG_EXTENDED) == 0;
83990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
84000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  EXPECT_TRUE(is_valid_)
84010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      << "Regular expression \"" << regex
84020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      << "\" is not a valid POSIX Extended regular expression.";
84030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
84040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  delete[] full_pattern;
84050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
84060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
84070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#elif GTEST_USES_SIMPLE_RE
84080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
84090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Returns true iff ch appears anywhere in str (excluding the
84100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// terminating '\0' character).
84110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgbool IsInSet(char ch, const char* str) {
84120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return ch != '\0' && strchr(str, ch) != NULL;
84130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
84140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
84150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Returns true iff ch belongs to the given classification.  Unlike
84160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// similar functions in <ctype.h>, these aren't affected by the
84170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// current locale.
84180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgbool IsAsciiDigit(char ch) { return '0' <= ch && ch <= '9'; }
84190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgbool IsAsciiPunct(char ch) {
84200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return IsInSet(ch, "^-!\"#$%&'()*+,./:;<=>?@[\\]_`{|}~");
84210d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
84220d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgbool IsRepeat(char ch) { return IsInSet(ch, "?*+"); }
84230d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgbool IsAsciiWhiteSpace(char ch) { return IsInSet(ch, " \f\n\r\t\v"); }
84240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgbool IsAsciiWordChar(char ch) {
84250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return ('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z') ||
84260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      ('0' <= ch && ch <= '9') || ch == '_';
84270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
84280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
84290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Returns true iff "\\c" is a supported escape sequence.
84300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgbool IsValidEscape(char c) {
84310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return (IsAsciiPunct(c) || IsInSet(c, "dDfnrsStvwW"));
84320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
84330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
84340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Returns true iff the given atom (specified by escaped and pattern)
84350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// matches ch.  The result is undefined if the atom is invalid.
84360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgbool AtomMatchesChar(bool escaped, char pattern_char, char ch) {
84370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (escaped) {  // "\\p" where p is pattern_char.
84380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    switch (pattern_char) {
84390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      case 'd': return IsAsciiDigit(ch);
84400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      case 'D': return !IsAsciiDigit(ch);
84410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      case 'f': return ch == '\f';
84420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      case 'n': return ch == '\n';
84430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      case 'r': return ch == '\r';
84440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      case 's': return IsAsciiWhiteSpace(ch);
84450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      case 'S': return !IsAsciiWhiteSpace(ch);
84460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      case 't': return ch == '\t';
84470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      case 'v': return ch == '\v';
84480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      case 'w': return IsAsciiWordChar(ch);
84490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      case 'W': return !IsAsciiWordChar(ch);
84500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    }
84510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return IsAsciiPunct(pattern_char) && pattern_char == ch;
84520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
84530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
84540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return (pattern_char == '.' && ch != '\n') || pattern_char == ch;
84550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
84560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
84570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Helper function used by ValidateRegex() to format error messages.
84580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstd::string FormatRegexSyntaxError(const char* regex, int index) {
84590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return (Message() << "Syntax error at index " << index
84600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          << " in simple regular expression \"" << regex << "\": ").GetString();
84610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
84620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
84630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Generates non-fatal failures and returns false if regex is invalid;
84640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// otherwise returns true.
84650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgbool ValidateRegex(const char* regex) {
84660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (regex == NULL) {
84670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // TODO(wan@google.com): fix the source file location in the
84680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // assertion failures to match where the regex is used in user
84690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // code.
84700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    ADD_FAILURE() << "NULL is not a valid simple regular expression.";
84710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return false;
84720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
84730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
84740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  bool is_valid = true;
84750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
84760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // True iff ?, *, or + can follow the previous atom.
84770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  bool prev_repeatable = false;
84780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  for (int i = 0; regex[i]; i++) {
84790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    if (regex[i] == '\\') {  // An escape sequence
84800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      i++;
84810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      if (regex[i] == '\0') {
84820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        ADD_FAILURE() << FormatRegexSyntaxError(regex, i - 1)
84830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                      << "'\\' cannot appear at the end.";
84840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        return false;
84850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      }
84860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
84870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      if (!IsValidEscape(regex[i])) {
84880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        ADD_FAILURE() << FormatRegexSyntaxError(regex, i - 1)
84890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                      << "invalid escape sequence \"\\" << regex[i] << "\".";
84900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        is_valid = false;
84910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      }
84920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      prev_repeatable = true;
84930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    } else {  // Not an escape sequence.
84940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      const char ch = regex[i];
84950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
84960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      if (ch == '^' && i > 0) {
84970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        ADD_FAILURE() << FormatRegexSyntaxError(regex, i)
84980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                      << "'^' can only appear at the beginning.";
84990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        is_valid = false;
85000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      } else if (ch == '$' && regex[i + 1] != '\0') {
85010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        ADD_FAILURE() << FormatRegexSyntaxError(regex, i)
85020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                      << "'$' can only appear at the end.";
85030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        is_valid = false;
85040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      } else if (IsInSet(ch, "()[]{}|")) {
85050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        ADD_FAILURE() << FormatRegexSyntaxError(regex, i)
85060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                      << "'" << ch << "' is unsupported.";
85070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        is_valid = false;
85080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      } else if (IsRepeat(ch) && !prev_repeatable) {
85090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        ADD_FAILURE() << FormatRegexSyntaxError(regex, i)
85100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                      << "'" << ch << "' can only follow a repeatable token.";
85110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        is_valid = false;
85120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      }
85130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
85140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      prev_repeatable = !IsInSet(ch, "^$?*+");
85150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    }
85160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
85170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
85180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return is_valid;
85190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
85200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
85210d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Matches a repeated regex atom followed by a valid simple regular
85220d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// expression.  The regex atom is defined as c if escaped is false,
85230d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// or \c otherwise.  repeat is the repetition meta character (?, *,
85240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// or +).  The behavior is undefined if str contains too many
85250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// characters to be indexable by size_t, in which case the test will
85260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// probably time out anyway.  We are fine with this limitation as
85270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// std::string has it too.
85280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgbool MatchRepetitionAndRegexAtHead(
85290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    bool escaped, char c, char repeat, const char* regex,
85300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const char* str) {
85310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const size_t min_count = (repeat == '+') ? 1 : 0;
85320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const size_t max_count = (repeat == '?') ? 1 :
85330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      static_cast<size_t>(-1) - 1;
85340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // We cannot call numeric_limits::max() as it conflicts with the
85350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // max() macro on Windows.
85360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
85370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  for (size_t i = 0; i <= max_count; ++i) {
85380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // We know that the atom matches each of the first i characters in str.
85390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    if (i >= min_count && MatchRegexAtHead(regex, str + i)) {
85400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      // We have enough matches at the head, and the tail matches too.
85410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      // Since we only care about *whether* the pattern matches str
85420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      // (as opposed to *how* it matches), there is no need to find a
85430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      // greedy match.
85440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      return true;
85450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    }
85460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    if (str[i] == '\0' || !AtomMatchesChar(escaped, c, str[i]))
85470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      return false;
85480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
85490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return false;
85500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
85510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
85520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Returns true iff regex matches a prefix of str.  regex must be a
85530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// valid simple regular expression and not start with "^", or the
85540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// result is undefined.
85550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgbool MatchRegexAtHead(const char* regex, const char* str) {
85560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (*regex == '\0')  // An empty regex matches a prefix of anything.
85570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return true;
85580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
85590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // "$" only matches the end of a string.  Note that regex being
85600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // valid guarantees that there's nothing after "$" in it.
85610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (*regex == '$')
85620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return *str == '\0';
85630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
85640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Is the first thing in regex an escape sequence?
85650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const bool escaped = *regex == '\\';
85660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (escaped)
85670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    ++regex;
85680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (IsRepeat(regex[1])) {
85690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // MatchRepetitionAndRegexAtHead() calls MatchRegexAtHead(), so
85700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // here's an indirect recursion.  It terminates as the regex gets
85710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // shorter in each recursion.
85720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return MatchRepetitionAndRegexAtHead(
85730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        escaped, regex[0], regex[1], regex + 2, str);
85740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  } else {
85750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // regex isn't empty, isn't "$", and doesn't start with a
85760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // repetition.  We match the first atom of regex with the first
85770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // character of str and recurse.
85780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return (*str != '\0') && AtomMatchesChar(escaped, *regex, *str) &&
85790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        MatchRegexAtHead(regex + 1, str + 1);
85800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
85810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
85820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
85830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Returns true iff regex matches any substring of str.  regex must be
85840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// a valid simple regular expression, or the result is undefined.
85850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
85860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// The algorithm is recursive, but the recursion depth doesn't exceed
85870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// the regex length, so we won't need to worry about running out of
85880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// stack space normally.  In rare cases the time complexity can be
85890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// exponential with respect to the regex length + the string length,
85900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// but usually it's must faster (often close to linear).
85910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgbool MatchRegexAnywhere(const char* regex, const char* str) {
85920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (regex == NULL || str == NULL)
85930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return false;
85940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
85950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (*regex == '^')
85960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return MatchRegexAtHead(regex + 1, str);
85970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
85980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // A successful match can be anywhere in str.
85990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  do {
86000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    if (MatchRegexAtHead(regex, str))
86010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      return true;
86020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  } while (*str++ != '\0');
86030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return false;
86040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
86050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
86060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Implements the RE class.
86070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
86080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgRE::~RE() {
86090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  free(const_cast<char*>(pattern_));
86100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  free(const_cast<char*>(full_pattern_));
86110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
86120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
86130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Returns true iff regular expression re matches the entire str.
86140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgbool RE::FullMatch(const char* str, const RE& re) {
86150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return re.is_valid_ && MatchRegexAnywhere(re.full_pattern_, str);
86160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
86170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
86180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Returns true iff regular expression re matches a substring of str
86190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// (including str itself).
86200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgbool RE::PartialMatch(const char* str, const RE& re) {
86210d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return re.is_valid_ && MatchRegexAnywhere(re.pattern_, str);
86220d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
86230d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
86240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Initializes an RE from its string representation.
86250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid RE::Init(const char* regex) {
86260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  pattern_ = full_pattern_ = NULL;
86270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (regex != NULL) {
86280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    pattern_ = posix::StrDup(regex);
86290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
86300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
86310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  is_valid_ = ValidateRegex(regex);
86320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (!is_valid_) {
86330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // No need to calculate the full pattern when the regex is invalid.
86340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return;
86350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
86360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
86370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const size_t len = strlen(regex);
86380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Reserves enough bytes to hold the regular expression used for a
86390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // full match: we need space to prepend a '^', append a '$', and
86400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // terminate the string with '\0'.
86410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  char* buffer = static_cast<char*>(malloc(len + 3));
86420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  full_pattern_ = buffer;
86430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
86440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (*regex != '^')
86450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    *buffer++ = '^';  // Makes sure full_pattern_ starts with '^'.
86460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
86470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // We don't use snprintf or strncpy, as they trigger a warning when
86480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // compiled with VC++ 8.0.
86490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  memcpy(buffer, regex, len);
86500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  buffer += len;
86510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
86520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (len == 0 || regex[len - 1] != '$')
86530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    *buffer++ = '$';  // Makes sure full_pattern_ ends with '$'.
86540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
86550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  *buffer = '\0';
86560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
86570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
86580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#endif  // GTEST_USES_POSIX_RE
86590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
86600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgconst char kUnknownFile[] = "unknown file";
86610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
86620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Formats a source file path and a line number as they would appear
86630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// in an error message from the compiler used to compile this code.
86640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgGTEST_API_ ::std::string FormatFileLocation(const char* file, int line) {
86650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const std::string file_name(file == NULL ? kUnknownFile : file);
86660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
86670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (line < 0) {
86680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return file_name + ":";
86690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
86700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#ifdef _MSC_VER
86710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return file_name + "(" + StreamableToString(line) + "):";
86720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#else
86730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return file_name + ":" + StreamableToString(line) + ":";
86740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#endif  // _MSC_VER
86750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
86760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
86770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Formats a file location for compiler-independent XML output.
86780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Although this function is not platform dependent, we put it next to
86790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// FormatFileLocation in order to contrast the two functions.
86800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Note that FormatCompilerIndependentFileLocation() does NOT append colon
86810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// to the file location it produces, unlike FormatFileLocation().
86820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgGTEST_API_ ::std::string FormatCompilerIndependentFileLocation(
86830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const char* file, int line) {
86840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const std::string file_name(file == NULL ? kUnknownFile : file);
86850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
86860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (line < 0)
86870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return file_name;
86880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  else
86890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return file_name + ":" + StreamableToString(line);
86900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
86910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
86920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
86930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgGTestLog::GTestLog(GTestLogSeverity severity, const char* file, int line)
86940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    : severity_(severity) {
86950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const char* const marker =
86960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      severity == GTEST_INFO ?    "[  INFO ]" :
86970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      severity == GTEST_WARNING ? "[WARNING]" :
86980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      severity == GTEST_ERROR ?   "[ ERROR ]" : "[ FATAL ]";
86990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  GetStream() << ::std::endl << marker << " "
87000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org              << FormatFileLocation(file, line).c_str() << ": ";
87010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
87020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
87030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Flushes the buffers and, if severity is GTEST_FATAL, aborts the program.
87040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgGTestLog::~GTestLog() {
87050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  GetStream() << ::std::endl;
87060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (severity_ == GTEST_FATAL) {
87070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    fflush(stderr);
87080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    posix::Abort();
87090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
87100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
87110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Disable Microsoft deprecation warnings for POSIX functions called from
87120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// this class (creat, dup, dup2, and close)
87130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#ifdef _MSC_VER
87140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# pragma warning(push)
87150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# pragma warning(disable: 4996)
87160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#endif  // _MSC_VER
87170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
87180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#if GTEST_HAS_STREAM_REDIRECTION
87190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
87200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Object that captures an output stream (stdout/stderr).
87210d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgclass CapturedStream {
87220d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org public:
87230d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // The ctor redirects the stream to a temporary file.
87240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  explicit CapturedStream(int fd) : fd_(fd), uncaptured_fd_(dup(fd)) {
87250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# if GTEST_OS_WINDOWS
87260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    char temp_dir_path[MAX_PATH + 1] = { '\0' };  // NOLINT
87270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    char temp_file_path[MAX_PATH + 1] = { '\0' };  // NOLINT
87280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
87290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    ::GetTempPathA(sizeof(temp_dir_path), temp_dir_path);
87300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const UINT success = ::GetTempFileNameA(temp_dir_path,
87310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                            "gtest_redir",
87320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                            0,  // Generate unique file name.
87330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                            temp_file_path);
87340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    GTEST_CHECK_(success != 0)
87350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        << "Unable to create a temporary file in " << temp_dir_path;
87360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const int captured_fd = creat(temp_file_path, _S_IREAD | _S_IWRITE);
87370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    GTEST_CHECK_(captured_fd != -1) << "Unable to open temporary file "
87380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                    << temp_file_path;
87390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    filename_ = temp_file_path;
87400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# else
87410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // There's no guarantee that a test has write access to the current
87420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // directory, so we create the temporary file in the /tmp directory
87430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // instead. We use /tmp on most systems, and /sdcard on Android.
87440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // That's because Android doesn't have /tmp.
87450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#  if GTEST_OS_LINUX_ANDROID
87460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // Note: Android applications are expected to call the framework's
87470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // Context.getExternalStorageDirectory() method through JNI to get
87480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // the location of the world-writable SD Card directory. However,
87490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // this requires a Context handle, which cannot be retrieved
87500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // globally from native code. Doing so also precludes running the
87510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // code as part of a regular standalone executable, which doesn't
87520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // run in a Dalvik process (e.g. when running it through 'adb shell').
87530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    //
87540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // The location /sdcard is directly accessible from native code
87550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // and is the only location (unofficially) supported by the Android
87560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // team. It's generally a symlink to the real SD Card mount point
87570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // which can be /mnt/sdcard, /mnt/sdcard0, /system/media/sdcard, or
87580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // other OEM-customized locations. Never rely on these, and always
87590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // use /sdcard.
87600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    char name_template[] = "/sdcard/gtest_captured_stream.XXXXXX";
87610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#  else
87620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    char name_template[] = "/tmp/captured_stream.XXXXXX";
87630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#  endif  // GTEST_OS_LINUX_ANDROID
87640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const int captured_fd = mkstemp(name_template);
87650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    filename_ = name_template;
87660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# endif  // GTEST_OS_WINDOWS
87670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    fflush(NULL);
87680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    dup2(captured_fd, fd_);
87690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    close(captured_fd);
87700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
87710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
87720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  ~CapturedStream() {
87730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    remove(filename_.c_str());
87740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
87750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
87760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  std::string GetCapturedString() {
87770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    if (uncaptured_fd_ != -1) {
87780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      // Restores the original stream.
87790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      fflush(NULL);
87800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      dup2(uncaptured_fd_, fd_);
87810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      close(uncaptured_fd_);
87820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      uncaptured_fd_ = -1;
87830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    }
87840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
87850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    FILE* const file = posix::FOpen(filename_.c_str(), "r");
87860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const std::string content = ReadEntireFile(file);
87870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    posix::FClose(file);
87880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return content;
87890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
87900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
87910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org private:
87920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Reads the entire content of a file as an std::string.
87930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  static std::string ReadEntireFile(FILE* file);
87940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
87950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Returns the size (in bytes) of a file.
87960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  static size_t GetFileSize(FILE* file);
87970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
87980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const int fd_;  // A stream to capture.
87990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  int uncaptured_fd_;
88000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Name of the temporary file holding the stderr output.
88010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  ::std::string filename_;
88020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
88030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  GTEST_DISALLOW_COPY_AND_ASSIGN_(CapturedStream);
88040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org};
88050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
88060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Returns the size (in bytes) of a file.
88070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgsize_t CapturedStream::GetFileSize(FILE* file) {
88080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  fseek(file, 0, SEEK_END);
88090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return static_cast<size_t>(ftell(file));
88100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
88110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
88120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Reads the entire content of a file as a string.
88130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstd::string CapturedStream::ReadEntireFile(FILE* file) {
88140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const size_t file_size = GetFileSize(file);
88150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  char* const buffer = new char[file_size];
88160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
88170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  size_t bytes_last_read = 0;  // # of bytes read in the last fread()
88180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  size_t bytes_read = 0;       // # of bytes read so far
88190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
88200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  fseek(file, 0, SEEK_SET);
88210d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
88220d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Keeps reading the file until we cannot read further or the
88230d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // pre-determined file size is reached.
88240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  do {
88250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    bytes_last_read = fread(buffer+bytes_read, 1, file_size-bytes_read, file);
88260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    bytes_read += bytes_last_read;
88270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  } while (bytes_last_read > 0 && bytes_read < file_size);
88280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
88290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const std::string content(buffer, bytes_read);
88300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  delete[] buffer;
88310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
88320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return content;
88330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
88340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
88350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# ifdef _MSC_VER
88360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#  pragma warning(pop)
88370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org# endif  // _MSC_VER
88380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
88390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstatic CapturedStream* g_captured_stderr = NULL;
88400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstatic CapturedStream* g_captured_stdout = NULL;
88410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
88420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Starts capturing an output stream (stdout/stderr).
88430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid CaptureStream(int fd, const char* stream_name, CapturedStream** stream) {
88440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (*stream != NULL) {
88450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    GTEST_LOG_(FATAL) << "Only one " << stream_name
88460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                      << " capturer can exist at a time.";
88470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
88480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  *stream = new CapturedStream(fd);
88490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
88500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
88510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Stops capturing the output stream and returns the captured string.
88520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstd::string GetCapturedStream(CapturedStream** captured_stream) {
88530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const std::string content = (*captured_stream)->GetCapturedString();
88540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
88550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  delete *captured_stream;
88560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  *captured_stream = NULL;
88570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
88580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return content;
88590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
88600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
88610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Starts capturing stdout.
88620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid CaptureStdout() {
88630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  CaptureStream(kStdOutFileno, "stdout", &g_captured_stdout);
88640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
88650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
88660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Starts capturing stderr.
88670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid CaptureStderr() {
88680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  CaptureStream(kStdErrFileno, "stderr", &g_captured_stderr);
88690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
88700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
88710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Stops capturing stdout and returns the captured string.
88720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstd::string GetCapturedStdout() {
88730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return GetCapturedStream(&g_captured_stdout);
88740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
88750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
88760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Stops capturing stderr and returns the captured string.
88770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstd::string GetCapturedStderr() {
88780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return GetCapturedStream(&g_captured_stderr);
88790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
88800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
88810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#endif  // GTEST_HAS_STREAM_REDIRECTION
88820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
88830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#if GTEST_HAS_DEATH_TEST
88840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
88850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// A copy of all command line arguments.  Set by InitGoogleTest().
88860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org::std::vector<testing::internal::string> g_argvs;
88870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
88880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstatic const ::std::vector<testing::internal::string>* g_injected_test_argvs =
88890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                        NULL;  // Owned.
88900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
88910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid SetInjectableArgvs(const ::std::vector<testing::internal::string>* argvs) {
88920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (g_injected_test_argvs != argvs)
88930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    delete g_injected_test_argvs;
88940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  g_injected_test_argvs = argvs;
88950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
88960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
88970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgconst ::std::vector<testing::internal::string>& GetInjectableArgvs() {
88980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (g_injected_test_argvs != NULL) {
88990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return *g_injected_test_argvs;
89000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
89010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return g_argvs;
89020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
89030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#endif  // GTEST_HAS_DEATH_TEST
89040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
89050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#if GTEST_OS_WINDOWS_MOBILE
89060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgnamespace posix {
89070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid Abort() {
89080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  DebugBreak();
89090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  TerminateProcess(GetCurrentProcess(), 1);
89100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
89110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}  // namespace posix
89120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#endif  // GTEST_OS_WINDOWS_MOBILE
89130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
89140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Returns the name of the environment variable corresponding to the
89150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// given flag.  For example, FlagToEnvVar("foo") will return
89160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// "GTEST_FOO" in the open-source version.
89170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstatic std::string FlagToEnvVar(const char* flag) {
89180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const std::string full_flag =
89190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      (Message() << GTEST_FLAG_PREFIX_ << flag).GetString();
89200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
89210d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  Message env_var;
89220d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  for (size_t i = 0; i != full_flag.length(); i++) {
89230d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    env_var << ToUpper(full_flag.c_str()[i]);
89240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
89250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
89260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return env_var.GetString();
89270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
89280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
89290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Parses 'str' for a 32-bit signed integer.  If successful, writes
89300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// the result to *value and returns true; otherwise leaves *value
89310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// unchanged and returns false.
89320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgbool ParseInt32(const Message& src_text, const char* str, Int32* value) {
89330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Parses the environment variable as a decimal integer.
89340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  char* end = NULL;
89350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const long long_value = strtol(str, &end, 10);  // NOLINT
89360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
89370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Has strtol() consumed all characters in the string?
89380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (*end != '\0') {
89390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // No - an invalid character was encountered.
89400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    Message msg;
89410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    msg << "WARNING: " << src_text
89420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        << " is expected to be a 32-bit integer, but actually"
89430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        << " has value \"" << str << "\".\n";
89440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    printf("%s", msg.GetString().c_str());
89450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    fflush(stdout);
89460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return false;
89470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
89480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
89490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Is the parsed value in the range of an Int32?
89500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const Int32 result = static_cast<Int32>(long_value);
89510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (long_value == LONG_MAX || long_value == LONG_MIN ||
89520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      // The parsed value overflows as a long.  (strtol() returns
89530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      // LONG_MAX or LONG_MIN when the input overflows.)
89540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      result != long_value
89550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      // The parsed value overflows as an Int32.
89560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      ) {
89570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    Message msg;
89580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    msg << "WARNING: " << src_text
89590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        << " is expected to be a 32-bit integer, but actually"
89600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        << " has value " << str << ", which overflows.\n";
89610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    printf("%s", msg.GetString().c_str());
89620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    fflush(stdout);
89630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return false;
89640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
89650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
89660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  *value = result;
89670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return true;
89680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
89690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
89700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Reads and returns the Boolean environment variable corresponding to
89710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// the given flag; if it's not set, returns default_value.
89720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
89730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// The value is considered true iff it's not "0".
89740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgbool BoolFromGTestEnv(const char* flag, bool default_value) {
89750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const std::string env_var = FlagToEnvVar(flag);
89760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const char* const string_value = posix::GetEnv(env_var.c_str());
89770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return string_value == NULL ?
89780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      default_value : strcmp(string_value, "0") != 0;
89790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
89800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
89810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Reads and returns a 32-bit integer stored in the environment
89820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// variable corresponding to the given flag; if it isn't set or
89830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// doesn't represent a valid 32-bit integer, returns default_value.
89840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgInt32 Int32FromGTestEnv(const char* flag, Int32 default_value) {
89850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const std::string env_var = FlagToEnvVar(flag);
89860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const char* const string_value = posix::GetEnv(env_var.c_str());
89870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (string_value == NULL) {
89880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // The environment variable is not set.
89890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return default_value;
89900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
89910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
89920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  Int32 result = default_value;
89930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (!ParseInt32(Message() << "Environment variable " << env_var,
89940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                  string_value, &result)) {
89950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    printf("The default value %s is used.\n",
89960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org           (Message() << default_value).GetString().c_str());
89970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    fflush(stdout);
89980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return default_value;
89990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
90000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
90010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return result;
90020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
90030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
90040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Reads and returns the string environment variable corresponding to
90050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// the given flag; if it's not set, returns default_value.
90060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgconst char* StringFromGTestEnv(const char* flag, const char* default_value) {
90070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const std::string env_var = FlagToEnvVar(flag);
90080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const char* const value = posix::GetEnv(env_var.c_str());
90090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return value == NULL ? default_value : value;
90100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
90110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
90120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}  // namespace internal
90130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}  // namespace testing
90140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Copyright 2007, Google Inc.
90150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// All rights reserved.
90160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
90170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Redistribution and use in source and binary forms, with or without
90180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// modification, are permitted provided that the following conditions are
90190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// met:
90200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
90210d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//     * Redistributions of source code must retain the above copyright
90220d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// notice, this list of conditions and the following disclaimer.
90230d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//     * Redistributions in binary form must reproduce the above
90240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// copyright notice, this list of conditions and the following disclaimer
90250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// in the documentation and/or other materials provided with the
90260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// distribution.
90270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//     * Neither the name of Google Inc. nor the names of its
90280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// contributors may be used to endorse or promote products derived from
90290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// this software without specific prior written permission.
90300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
90310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
90320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
90330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
90340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
90350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
90360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
90370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
90380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
90390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
90400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
90410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
90420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
90430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Author: wan@google.com (Zhanyong Wan)
90440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
90450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Google Test - The Google C++ Testing Framework
90460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
90470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// This file implements a universal value printer that can print a
90480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// value of any type T:
90490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
90500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//   void ::testing::internal::UniversalPrinter<T>::Print(value, ostream_ptr);
90510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
90520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// It uses the << operator when possible, and prints the bytes in the
90530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// object otherwise.  A user can override its behavior for a class
90540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// type Foo by defining either operator<<(::std::ostream&, const Foo&)
90550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// or void PrintTo(const Foo&, ::std::ostream*) in the namespace that
90560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// defines Foo.
90570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
90580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#include <ctype.h>
90590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#include <stdio.h>
90600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#include <ostream>  // NOLINT
90610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#include <string>
90620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
90630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgnamespace testing {
90640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
90650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgnamespace {
90660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
90670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgusing ::std::ostream;
90680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
90690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Prints a segment of bytes in the given object.
90700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid PrintByteSegmentInObjectTo(const unsigned char* obj_bytes, size_t start,
90710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                                size_t count, ostream* os) {
90720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  char text[5] = "";
90730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  for (size_t i = 0; i != count; i++) {
90740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const size_t j = start + i;
90750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    if (i != 0) {
90760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      // Organizes the bytes into groups of 2 for easy parsing by
90770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      // human.
90780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      if ((j % 2) == 0)
90790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        *os << ' ';
90800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      else
90810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        *os << '-';
90820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    }
90830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    GTEST_SNPRINTF_(text, sizeof(text), "%02X", obj_bytes[j]);
90840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    *os << text;
90850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
90860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
90870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
90880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Prints the bytes in the given value to the given ostream.
90890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid PrintBytesInObjectToImpl(const unsigned char* obj_bytes, size_t count,
90900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                              ostream* os) {
90910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Tells the user how big the object is.
90920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  *os << count << "-byte object <";
90930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
90940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const size_t kThreshold = 132;
90950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const size_t kChunkSize = 64;
90960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // If the object size is bigger than kThreshold, we'll have to omit
90970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // some details by printing only the first and the last kChunkSize
90980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // bytes.
90990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // TODO(wan): let the user control the threshold using a flag.
91000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (count < kThreshold) {
91010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    PrintByteSegmentInObjectTo(obj_bytes, 0, count, os);
91020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  } else {
91030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    PrintByteSegmentInObjectTo(obj_bytes, 0, kChunkSize, os);
91040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    *os << " ... ";
91050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // Rounds up to 2-byte boundary.
91060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const size_t resume_pos = (count - kChunkSize + 1)/2*2;
91070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    PrintByteSegmentInObjectTo(obj_bytes, resume_pos, count - resume_pos, os);
91080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
91090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  *os << ">";
91100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
91110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
91120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}  // namespace
91130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
91140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgnamespace internal2 {
91150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
91160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Delegates to PrintBytesInObjectToImpl() to print the bytes in the
91170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// given object.  The delegation simplifies the implementation, which
91180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// uses the << operator and thus is easier done outside of the
91190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// ::testing::internal namespace, which contains a << operator that
91200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// sometimes conflicts with the one in STL.
91210d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid PrintBytesInObjectTo(const unsigned char* obj_bytes, size_t count,
91220d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                          ostream* os) {
91230d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  PrintBytesInObjectToImpl(obj_bytes, count, os);
91240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
91250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
91260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}  // namespace internal2
91270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
91280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgnamespace internal {
91290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
91300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Depending on the value of a char (or wchar_t), we print it in one
91310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// of three formats:
91320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//   - as is if it's a printable ASCII (e.g. 'a', '2', ' '),
91330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//   - as a hexidecimal escape sequence (e.g. '\x7F'), or
91340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//   - as a special escape sequence (e.g. '\r', '\n').
91350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgenum CharFormat {
91360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  kAsIs,
91370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  kHexEscape,
91380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  kSpecialEscape
91390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org};
91400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
91410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Returns true if c is a printable ASCII character.  We test the
91420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// value of c directly instead of calling isprint(), which is buggy on
91430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Windows Mobile.
91440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orginline bool IsPrintableAscii(wchar_t c) {
91450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return 0x20 <= c && c <= 0x7E;
91460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
91470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
91480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Prints a wide or narrow char c as a character literal without the
91490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// quotes, escaping it when necessary; returns how c was formatted.
91500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// The template argument UnsignedChar is the unsigned version of Char,
91510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// which is the type of c.
91520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgtemplate <typename UnsignedChar, typename Char>
91530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstatic CharFormat PrintAsCharLiteralTo(Char c, ostream* os) {
91540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  switch (static_cast<wchar_t>(c)) {
91550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    case L'\0':
91560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      *os << "\\0";
91570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      break;
91580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    case L'\'':
91590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      *os << "\\'";
91600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      break;
91610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    case L'\\':
91620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      *os << "\\\\";
91630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      break;
91640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    case L'\a':
91650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      *os << "\\a";
91660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      break;
91670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    case L'\b':
91680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      *os << "\\b";
91690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      break;
91700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    case L'\f':
91710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      *os << "\\f";
91720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      break;
91730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    case L'\n':
91740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      *os << "\\n";
91750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      break;
91760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    case L'\r':
91770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      *os << "\\r";
91780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      break;
91790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    case L'\t':
91800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      *os << "\\t";
91810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      break;
91820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    case L'\v':
91830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      *os << "\\v";
91840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      break;
91850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    default:
91860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      if (IsPrintableAscii(c)) {
91870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        *os << static_cast<char>(c);
91880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        return kAsIs;
91890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      } else {
91900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        *os << "\\x" + String::FormatHexInt(static_cast<UnsignedChar>(c));
91910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        return kHexEscape;
91920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      }
91930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
91940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return kSpecialEscape;
91950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
91960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
91970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Prints a wchar_t c as if it's part of a string literal, escaping it when
91980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// necessary; returns how c was formatted.
91990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstatic CharFormat PrintAsStringLiteralTo(wchar_t c, ostream* os) {
92000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  switch (c) {
92010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    case L'\'':
92020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      *os << "'";
92030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      return kAsIs;
92040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    case L'"':
92050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      *os << "\\\"";
92060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      return kSpecialEscape;
92070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    default:
92080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      return PrintAsCharLiteralTo<wchar_t>(c, os);
92090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
92100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
92110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
92120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Prints a char c as if it's part of a string literal, escaping it when
92130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// necessary; returns how c was formatted.
92140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstatic CharFormat PrintAsStringLiteralTo(char c, ostream* os) {
92150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return PrintAsStringLiteralTo(
92160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      static_cast<wchar_t>(static_cast<unsigned char>(c)), os);
92170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
92180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
92190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Prints a wide or narrow character c and its code.  '\0' is printed
92200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// as "'\\0'", other unprintable characters are also properly escaped
92210d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// using the standard C++ escape sequence.  The template argument
92220d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// UnsignedChar is the unsigned version of Char, which is the type of c.
92230d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgtemplate <typename UnsignedChar, typename Char>
92240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid PrintCharAndCodeTo(Char c, ostream* os) {
92250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // First, print c as a literal in the most readable form we can find.
92260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  *os << ((sizeof(c) > 1) ? "L'" : "'");
92270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const CharFormat format = PrintAsCharLiteralTo<UnsignedChar>(c, os);
92280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  *os << "'";
92290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
92300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // To aid user debugging, we also print c's code in decimal, unless
92310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // it's 0 (in which case c was printed as '\\0', making the code
92320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // obvious).
92330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (c == 0)
92340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return;
92350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  *os << " (" << static_cast<int>(c);
92360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
92370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // For more convenience, we print c's code again in hexidecimal,
92380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // unless c was already printed in the form '\x##' or the code is in
92390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // [1, 9].
92400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (format == kHexEscape || (1 <= c && c <= 9)) {
92410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    // Do nothing.
92420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  } else {
92430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    *os << ", 0x" << String::FormatHexInt(static_cast<UnsignedChar>(c));
92440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
92450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  *os << ")";
92460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
92470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
92480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid PrintTo(unsigned char c, ::std::ostream* os) {
92490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  PrintCharAndCodeTo<unsigned char>(c, os);
92500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
92510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid PrintTo(signed char c, ::std::ostream* os) {
92520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  PrintCharAndCodeTo<unsigned char>(c, os);
92530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
92540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
92550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Prints a wchar_t as a symbol if it is printable or as its internal
92560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// code otherwise and also as its code.  L'\0' is printed as "L'\\0'".
92570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid PrintTo(wchar_t wc, ostream* os) {
92580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  PrintCharAndCodeTo<wchar_t>(wc, os);
92590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
92600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
92610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Prints the given array of characters to the ostream.  CharType must be either
92620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// char or wchar_t.
92630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// The array starts at begin, the length is len, it may include '\0' characters
92640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// and may not be NUL-terminated.
92650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgtemplate <typename CharType>
92660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstatic void PrintCharsAsStringTo(
92670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const CharType* begin, size_t len, ostream* os) {
92680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const char* const kQuoteBegin = sizeof(CharType) == 1 ? "\"" : "L\"";
92690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  *os << kQuoteBegin;
92700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  bool is_previous_hex = false;
92710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  for (size_t index = 0; index < len; ++index) {
92720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const CharType cur = begin[index];
92730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    if (is_previous_hex && IsXDigit(cur)) {
92740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      // Previous character is of '\x..' form and this character can be
92750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      // interpreted as another hexadecimal digit in its number. Break string to
92760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      // disambiguate.
92770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      *os << "\" " << kQuoteBegin;
92780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    }
92790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    is_previous_hex = PrintAsStringLiteralTo(cur, os) == kHexEscape;
92800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
92810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  *os << "\"";
92820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
92830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
92840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Prints a (const) char/wchar_t array of 'len' elements, starting at address
92850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// 'begin'.  CharType must be either char or wchar_t.
92860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgtemplate <typename CharType>
92870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstatic void UniversalPrintCharArray(
92880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const CharType* begin, size_t len, ostream* os) {
92890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // The code
92900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  //   const char kFoo[] = "foo";
92910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // generates an array of 4, not 3, elements, with the last one being '\0'.
92920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  //
92930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Therefore when printing a char array, we don't print the last element if
92940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // it's '\0', such that the output matches the string literal as it's
92950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // written in the source code.
92960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (len > 0 && begin[len - 1] == '\0') {
92970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    PrintCharsAsStringTo(begin, len - 1, os);
92980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    return;
92990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
93000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
93010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // If, however, the last element in the array is not '\0', e.g.
93020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  //    const char kFoo[] = { 'f', 'o', 'o' };
93030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // we must print the entire array.  We also print a message to indicate
93040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // that the array is not NUL-terminated.
93050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  PrintCharsAsStringTo(begin, len, os);
93060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  *os << " (no terminating NUL)";
93070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
93080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
93090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Prints a (const) char array of 'len' elements, starting at address 'begin'.
93100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid UniversalPrintArray(const char* begin, size_t len, ostream* os) {
93110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  UniversalPrintCharArray(begin, len, os);
93120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
93130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
93140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Prints a (const) wchar_t array of 'len' elements, starting at address
93150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// 'begin'.
93160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid UniversalPrintArray(const wchar_t* begin, size_t len, ostream* os) {
93170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  UniversalPrintCharArray(begin, len, os);
93180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
93190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
93200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Prints the given C string to the ostream.
93210d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid PrintTo(const char* s, ostream* os) {
93220d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (s == NULL) {
93230d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    *os << "NULL";
93240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  } else {
93250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    *os << ImplicitCast_<const void*>(s) << " pointing to ";
93260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    PrintCharsAsStringTo(s, strlen(s), os);
93270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
93280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
93290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
93300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// MSVC compiler can be configured to define whar_t as a typedef
93310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// of unsigned short. Defining an overload for const wchar_t* in that case
93320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// would cause pointers to unsigned shorts be printed as wide strings,
93330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// possibly accessing more memory than intended and causing invalid
93340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// memory accesses. MSVC defines _NATIVE_WCHAR_T_DEFINED symbol when
93350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// wchar_t is implemented as a native type.
93360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED)
93370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Prints the given wide C string to the ostream.
93380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid PrintTo(const wchar_t* s, ostream* os) {
93390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (s == NULL) {
93400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    *os << "NULL";
93410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  } else {
93420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    *os << ImplicitCast_<const void*>(s) << " pointing to ";
93430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    PrintCharsAsStringTo(s, wcslen(s), os);
93440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
93450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
93460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#endif  // wchar_t is native
93470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
93480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Prints a ::string object.
93490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#if GTEST_HAS_GLOBAL_STRING
93500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid PrintStringTo(const ::string& s, ostream* os) {
93510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  PrintCharsAsStringTo(s.data(), s.size(), os);
93520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
93530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#endif  // GTEST_HAS_GLOBAL_STRING
93540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
93550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid PrintStringTo(const ::std::string& s, ostream* os) {
93560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  PrintCharsAsStringTo(s.data(), s.size(), os);
93570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
93580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
93590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Prints a ::wstring object.
93600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#if GTEST_HAS_GLOBAL_WSTRING
93610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid PrintWideStringTo(const ::wstring& s, ostream* os) {
93620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  PrintCharsAsStringTo(s.data(), s.size(), os);
93630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
93640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#endif  // GTEST_HAS_GLOBAL_WSTRING
93650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
93660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#if GTEST_HAS_STD_WSTRING
93670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid PrintWideStringTo(const ::std::wstring& s, ostream* os) {
93680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  PrintCharsAsStringTo(s.data(), s.size(), os);
93690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
93700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#endif  // GTEST_HAS_STD_WSTRING
93710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
93720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}  // namespace internal
93730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
93740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}  // namespace testing
93750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Copyright 2008, Google Inc.
93760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// All rights reserved.
93770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
93780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Redistribution and use in source and binary forms, with or without
93790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// modification, are permitted provided that the following conditions are
93800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// met:
93810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
93820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//     * Redistributions of source code must retain the above copyright
93830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// notice, this list of conditions and the following disclaimer.
93840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//     * Redistributions in binary form must reproduce the above
93850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// copyright notice, this list of conditions and the following disclaimer
93860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// in the documentation and/or other materials provided with the
93870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// distribution.
93880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//     * Neither the name of Google Inc. nor the names of its
93890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// contributors may be used to endorse or promote products derived from
93900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// this software without specific prior written permission.
93910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
93920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
93930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
93940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
93950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
93960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
93970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
93980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
93990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
94000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
94010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
94020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
94030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
94040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Author: mheule@google.com (Markus Heule)
94050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
94060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// The Google C++ Testing Framework (Google Test)
94070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
94080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
94090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Indicates that this translation unit is part of Google Test's
94100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// implementation.  It must come before gtest-internal-inl.h is
94110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// included, or there will be a compiler error.  This trick is to
94120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// prevent a user from accidentally including gtest-internal-inl.h in
94130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// his code.
94140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#define GTEST_IMPLEMENTATION_ 1
94150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#undef GTEST_IMPLEMENTATION_
94160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
94170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgnamespace testing {
94180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
94190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgusing internal::GetUnitTestImpl;
94200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
94210d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Gets the summary of the failure message by omitting the stack trace
94220d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// in it.
94230d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstd::string TestPartResult::ExtractSummary(const char* message) {
94240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const char* const stack_trace = strstr(message, internal::kStackTraceMarker);
94250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return stack_trace == NULL ? message :
94260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      std::string(message, stack_trace);
94270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
94280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
94290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Prints a TestPartResult object.
94300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstd::ostream& operator<<(std::ostream& os, const TestPartResult& result) {
94310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return os
94320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      << result.file_name() << ":" << result.line_number() << ": "
94330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      << (result.type() == TestPartResult::kSuccess ? "Success" :
94340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          result.type() == TestPartResult::kFatalFailure ? "Fatal failure" :
94350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          "Non-fatal failure") << ":\n"
94360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      << result.message() << std::endl;
94370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
94380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
94390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Appends a TestPartResult to the array.
94400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid TestPartResultArray::Append(const TestPartResult& result) {
94410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  array_.push_back(result);
94420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
94430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
94440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Returns the TestPartResult at the given index (0-based).
94450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgconst TestPartResult& TestPartResultArray::GetTestPartResult(int index) const {
94460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (index < 0 || index >= size()) {
94470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    printf("\nInvalid index (%d) into TestPartResultArray.\n", index);
94480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    internal::posix::Abort();
94490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
94500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
94510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return array_[index];
94520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
94530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
94540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Returns the number of TestPartResult objects in the array.
94550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgint TestPartResultArray::size() const {
94560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return static_cast<int>(array_.size());
94570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
94580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
94590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgnamespace internal {
94600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
94610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgHasNewFatalFailureHelper::HasNewFatalFailureHelper()
94620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    : has_new_fatal_failure_(false),
94630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      original_reporter_(GetUnitTestImpl()->
94640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                         GetTestPartResultReporterForCurrentThread()) {
94650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread(this);
94660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
94670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
94680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgHasNewFatalFailureHelper::~HasNewFatalFailureHelper() {
94690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread(
94700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      original_reporter_);
94710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
94720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
94730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid HasNewFatalFailureHelper::ReportTestPartResult(
94740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const TestPartResult& result) {
94750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (result.fatally_failed())
94760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    has_new_fatal_failure_ = true;
94770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  original_reporter_->ReportTestPartResult(result);
94780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
94790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
94800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}  // namespace internal
94810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
94820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}  // namespace testing
94830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Copyright 2008 Google Inc.
94840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// All Rights Reserved.
94850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
94860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Redistribution and use in source and binary forms, with or without
94870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// modification, are permitted provided that the following conditions are
94880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// met:
94890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
94900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//     * Redistributions of source code must retain the above copyright
94910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// notice, this list of conditions and the following disclaimer.
94920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//     * Redistributions in binary form must reproduce the above
94930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// copyright notice, this list of conditions and the following disclaimer
94940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// in the documentation and/or other materials provided with the
94950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// distribution.
94960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//     * Neither the name of Google Inc. nor the names of its
94970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// contributors may be used to endorse or promote products derived from
94980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// this software without specific prior written permission.
94990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
95000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
95010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
95020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
95030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
95040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
95050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
95060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
95070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
95080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
95090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
95100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
95110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org//
95120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Author: wan@google.com (Zhanyong Wan)
95130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
95140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
95150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgnamespace testing {
95160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgnamespace internal {
95170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
95180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#if GTEST_HAS_TYPED_TEST_P
95190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
95200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Skips to the first non-space char in str. Returns an empty string if str
95210d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// contains only whitespace characters.
95220d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgstatic const char* SkipSpaces(const char* str) {
95230d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  while (IsSpace(*str))
95240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    str++;
95250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return str;
95260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
95270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
95280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// Verifies that registered_tests match the test names in
95290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// defined_test_names_; returns registered_tests if successful, or
95300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org// aborts the program otherwise.
95310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgconst char* TypedTestCasePState::VerifyRegisteredTestNames(
95320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const char* file, int line, const char* registered_tests) {
95330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  typedef ::std::set<const char*>::const_iterator DefinedTestIter;
95340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  registered_ = true;
95350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
95360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // Skip initial whitespace in registered_tests since some
95370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  // preprocessors prefix stringizied literals with whitespace.
95380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  registered_tests = SkipSpaces(registered_tests);
95390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
95400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  Message errors;
95410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  ::std::set<std::string> tests;
95420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  for (const char* names = registered_tests; names != NULL;
95430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org       names = SkipComma(names)) {
95440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const std::string name = GetPrefixUntilComma(names);
95450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    if (tests.count(name) != 0) {
95460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      errors << "Test " << name << " is listed more than once.\n";
95470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      continue;
95480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    }
95490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
95500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    bool found = false;
95510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    for (DefinedTestIter it = defined_test_names_.begin();
95520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org         it != defined_test_names_.end();
95530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org         ++it) {
95540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      if (name == *it) {
95550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        found = true;
95560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        break;
95570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      }
95580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    }
95590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
95600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    if (found) {
95610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      tests.insert(name);
95620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    } else {
95630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      errors << "No test named " << name
95640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org             << " can be found in this test case.\n";
95650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    }
95660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
95670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
95680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  for (DefinedTestIter it = defined_test_names_.begin();
95690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org       it != defined_test_names_.end();
95700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org       ++it) {
95710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    if (tests.count(*it) == 0) {
95720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      errors << "You forgot to list test " << *it << ".\n";
95730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    }
95740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
95750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
95760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  const std::string& errors_str = errors.GetString();
95770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  if (errors_str != "") {
95780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    fprintf(stderr, "%s %s", FormatFileLocation(file, line).c_str(),
95790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org            errors_str.c_str());
95800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    fflush(stderr);
95810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    posix::Abort();
95820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
95830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
95840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  return registered_tests;
95850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
95860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
95870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#endif  // GTEST_HAS_TYPED_TEST_P
95880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
95890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}  // namespace internal
95900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}  // namespace testing
9591