| 1 | // Copyright 2007, Google Inc. | 
|---|
| 2 | // All rights reserved. | 
|---|
| 3 | // | 
|---|
| 4 | // Redistribution and use in source and binary forms, with or without | 
|---|
| 5 | // modification, are permitted provided that the following conditions are | 
|---|
| 6 | // met: | 
|---|
| 7 | // | 
|---|
| 8 | //     * Redistributions of source code must retain the above copyright | 
|---|
| 9 | // notice, this list of conditions and the following disclaimer. | 
|---|
| 10 | //     * Redistributions in binary form must reproduce the above | 
|---|
| 11 | // copyright notice, this list of conditions and the following disclaimer | 
|---|
| 12 | // in the documentation and/or other materials provided with the | 
|---|
| 13 | // distribution. | 
|---|
| 14 | //     * Neither the name of Google Inc. nor the names of its | 
|---|
| 15 | // contributors may be used to endorse or promote products derived from | 
|---|
| 16 | // this software without specific prior written permission. | 
|---|
| 17 | // | 
|---|
| 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | 
|---|
| 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | 
|---|
| 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | 
|---|
| 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | 
|---|
| 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | 
|---|
| 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 
|---|
| 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 
|---|
| 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 
|---|
| 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 
|---|
| 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 
|---|
| 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 
|---|
| 29 | // | 
|---|
| 30 | // Author: wan@google.com (Zhanyong Wan) | 
|---|
| 31 |  | 
|---|
| 32 | // Google Mock - a framework for writing C++ mock classes. | 
|---|
| 33 | // | 
|---|
| 34 | // This file defines some utilities useful for implementing Google | 
|---|
| 35 | // Mock.  They are subject to change without notice, so please DO NOT | 
|---|
| 36 | // USE THEM IN USER CODE. | 
|---|
| 37 |  | 
|---|
| 38 | #include "gmock/internal/gmock-internal-utils.h" | 
|---|
| 39 |  | 
|---|
| 40 | #include <ctype.h> | 
|---|
| 41 | #include <ostream>  // NOLINT | 
|---|
| 42 | #include <string> | 
|---|
| 43 | #include "gmock/gmock.h" | 
|---|
| 44 | #include "gmock/internal/gmock-port.h" | 
|---|
| 45 | #include "gtest/gtest.h" | 
|---|
| 46 |  | 
|---|
| 47 | namespace testing { | 
|---|
| 48 | namespace internal { | 
|---|
| 49 |  | 
|---|
| 50 | // Converts an identifier name to a space-separated list of lower-case | 
|---|
| 51 | // words.  Each maximum substring of the form [A-Za-z][a-z]*|\d+ is | 
|---|
| 52 | // treated as one word.  For example, both "FooBar123" and | 
|---|
| 53 | // "foo_bar_123" are converted to "foo bar 123". | 
|---|
| 54 | string ConvertIdentifierNameToWords(const char* id_name) { | 
|---|
| 55 |   string result; | 
|---|
| 56 |   char prev_char = '\0'; | 
|---|
| 57 |   for (const char* p = id_name; *p != '\0'; prev_char = *(p++)) { | 
|---|
| 58 |     // We don't care about the current locale as the input is | 
|---|
| 59 |     // guaranteed to be a valid C++ identifier name. | 
|---|
| 60 |     const bool starts_new_word = IsUpper(*p) || | 
|---|
| 61 |         (!IsAlpha(prev_char) && IsLower(*p)) || | 
|---|
| 62 |         (!IsDigit(prev_char) && IsDigit(*p)); | 
|---|
| 63 |  | 
|---|
| 64 |     if (IsAlNum(*p)) { | 
|---|
| 65 |       if (starts_new_word && result != "") | 
|---|
| 66 |         result += ' '; | 
|---|
| 67 |       result += ToLower(*p); | 
|---|
| 68 |     } | 
|---|
| 69 |   } | 
|---|
| 70 |   return result; | 
|---|
| 71 | } | 
|---|
| 72 |  | 
|---|
| 73 | // This class reports Google Mock failures as Google Test failures.  A | 
|---|
| 74 | // user can define another class in a similar fashion if he intends to | 
|---|
| 75 | // use Google Mock with a testing framework other than Google Test. | 
|---|
| 76 | class GoogleTestFailureReporter : public FailureReporterInterface { | 
|---|
| 77 |  public: | 
|---|
| 78 |   virtual void ReportFailure(FailureType type, const char* file, int line, | 
|---|
| 79 |                              const string& message) { | 
|---|
| 80 |     AssertHelper(type == FATAL ? | 
|---|
| 81 |                  TestPartResult::kFatalFailure : | 
|---|
| 82 |                  TestPartResult::kNonFatalFailure, | 
|---|
| 83 |                  file, | 
|---|
| 84 |                  line, | 
|---|
| 85 |                  message.c_str()) = Message(); | 
|---|
| 86 |     if (type == FATAL) { | 
|---|
| 87 |       posix::Abort(); | 
|---|
| 88 |     } | 
|---|
| 89 |   } | 
|---|
| 90 | }; | 
|---|
| 91 |  | 
|---|
| 92 | // Returns the global failure reporter.  Will create a | 
|---|
| 93 | // GoogleTestFailureReporter and return it the first time called. | 
|---|
| 94 | FailureReporterInterface* GetFailureReporter() { | 
|---|
| 95 |   // Points to the global failure reporter used by Google Mock.  gcc | 
|---|
| 96 |   // guarantees that the following use of failure_reporter is | 
|---|
| 97 |   // thread-safe.  We may need to add additional synchronization to | 
|---|
| 98 |   // protect failure_reporter if we port Google Mock to other | 
|---|
| 99 |   // compilers. | 
|---|
| 100 |   static FailureReporterInterface* const failure_reporter = | 
|---|
| 101 |       new GoogleTestFailureReporter(); | 
|---|
| 102 |   return failure_reporter; | 
|---|
| 103 | } | 
|---|
| 104 |  | 
|---|
| 105 | // Protects global resources (stdout in particular) used by Log(). | 
|---|
| 106 | static GTEST_DEFINE_STATIC_MUTEX_(g_log_mutex); | 
|---|
| 107 |  | 
|---|
| 108 | // Returns true iff a log with the given severity is visible according | 
|---|
| 109 | // to the --gmock_verbose flag. | 
|---|
| 110 | bool LogIsVisible(LogSeverity severity) { | 
|---|
| 111 |   if (GMOCK_FLAG(verbose) == kInfoVerbosity) { | 
|---|
| 112 |     // Always show the log if --gmock_verbose=info. | 
|---|
| 113 |     return true; | 
|---|
| 114 |   } else if (GMOCK_FLAG(verbose) == kErrorVerbosity) { | 
|---|
| 115 |     // Always hide it if --gmock_verbose=error. | 
|---|
| 116 |     return false; | 
|---|
| 117 |   } else { | 
|---|
| 118 |     // If --gmock_verbose is neither "info" nor "error", we treat it | 
|---|
| 119 |     // as "warning" (its default value). | 
|---|
| 120 |     return severity == WARNING; | 
|---|
| 121 |   } | 
|---|
| 122 | } | 
|---|
| 123 |  | 
|---|
| 124 | // Prints the given message to stdout iff 'severity' >= the level | 
|---|
| 125 | // specified by the --gmock_verbose flag.  If stack_frames_to_skip >= | 
|---|
| 126 | // 0, also prints the stack trace excluding the top | 
|---|
| 127 | // stack_frames_to_skip frames.  In opt mode, any positive | 
|---|
| 128 | // stack_frames_to_skip is treated as 0, since we don't know which | 
|---|
| 129 | // function calls will be inlined by the compiler and need to be | 
|---|
| 130 | // conservative. | 
|---|
| 131 | void Log(LogSeverity severity, const string& message, | 
|---|
| 132 |          int stack_frames_to_skip) { | 
|---|
| 133 |   if (!LogIsVisible(severity)) | 
|---|
| 134 |     return; | 
|---|
| 135 |  | 
|---|
| 136 |   // Ensures that logs from different threads don't interleave. | 
|---|
| 137 |   MutexLock l(&g_log_mutex); | 
|---|
| 138 |  | 
|---|
| 139 |   // "using ::std::cout;" doesn't work with Symbian's STLport, where cout is a | 
|---|
| 140 |   // macro. | 
|---|
| 141 |  | 
|---|
| 142 |   if (severity == WARNING) { | 
|---|
| 143 |     // Prints a GMOCK WARNING marker to make the warnings easily searchable. | 
|---|
| 144 |     std::cout << "\nGMOCK WARNING:"; | 
|---|
| 145 |   } | 
|---|
| 146 |   // Pre-pends a new-line to message if it doesn't start with one. | 
|---|
| 147 |   if (message.empty() || message[0] != '\n') { | 
|---|
| 148 |     std::cout << "\n"; | 
|---|
| 149 |   } | 
|---|
| 150 |   std::cout << message; | 
|---|
| 151 |   if (stack_frames_to_skip >= 0) { | 
|---|
| 152 | #ifdef NDEBUG | 
|---|
| 153 |     // In opt mode, we have to be conservative and skip no stack frame. | 
|---|
| 154 |     const int actual_to_skip = 0; | 
|---|
| 155 | #else | 
|---|
| 156 |     // In dbg mode, we can do what the caller tell us to do (plus one | 
|---|
| 157 |     // for skipping this function's stack frame). | 
|---|
| 158 |     const int actual_to_skip = stack_frames_to_skip + 1; | 
|---|
| 159 | #endif  // NDEBUG | 
|---|
| 160 |  | 
|---|
| 161 |     // Appends a new-line to message if it doesn't end with one. | 
|---|
| 162 |     if (!message.empty() && *message.rbegin() != '\n') { | 
|---|
| 163 |       std::cout << "\n"; | 
|---|
| 164 |     } | 
|---|
| 165 |     std::cout << "Stack trace:\n" | 
|---|
| 166 |          << ::testing::internal::GetCurrentOsStackTraceExceptTop( | 
|---|
| 167 |              ::testing::UnitTest::GetInstance(), actual_to_skip); | 
|---|
| 168 |   } | 
|---|
| 169 |   std::cout << ::std::flush; | 
|---|
| 170 | } | 
|---|
| 171 |  | 
|---|
| 172 | }  // namespace internal | 
|---|
| 173 | }  // namespace testing | 
|---|