141d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// Copyright 2007, Google Inc. 241d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// All rights reserved. 341d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// 441d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// Redistribution and use in source and binary forms, with or without 541d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// modification, are permitted provided that the following conditions are 641d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// met: 741d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// 841d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// * Redistributions of source code must retain the above copyright 941d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// notice, this list of conditions and the following disclaimer. 1041d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// * Redistributions in binary form must reproduce the above 1141d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// copyright notice, this list of conditions and the following disclaimer 1241d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// in the documentation and/or other materials provided with the 1341d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// distribution. 1441d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// * Neither the name of Google Inc. nor the names of its 1541d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// contributors may be used to endorse or promote products derived from 1641d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// this software without specific prior written permission. 1741d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// 1841d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1941d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2041d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2141d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2241d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2341d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2441d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2541d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2641d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2741d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2841d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2941d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// 3041d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// Author: wan@google.com (Zhanyong Wan) 3141d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot 3241d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// Google Test - The Google C++ Testing Framework 3341d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// 3441d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// This file implements a universal value printer that can print a 3541d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// value of any type T: 3641d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// 3741d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// void ::testing::internal::UniversalPrinter<T>::Print(value, ostream_ptr); 3841d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// 3941d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// It uses the << operator when possible, and prints the bytes in the 4041d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// object otherwise. A user can override its behavior for a class 4141d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// type Foo by defining either operator<<(::std::ostream&, const Foo&) 4241d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// or void PrintTo(const Foo&, ::std::ostream*) in the namespace that 4341d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// defines Foo. 4441d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot 4541d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot#include "gtest/gtest-printers.h" 4641d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot#include <ctype.h> 4741d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot#include <stdio.h> 4841d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot#include <ostream> // NOLINT 4941d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot#include <string> 5041d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot#include "gtest/internal/gtest-port.h" 5141d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot 5241d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabotnamespace testing { 5341d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot 5441d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabotnamespace { 5541d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot 5641d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabotusing ::std::ostream; 5741d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot 5841d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot#if GTEST_OS_WINDOWS_MOBILE // Windows CE does not define _snprintf_s. 5941d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot# define snprintf _snprintf 6041d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot#elif _MSC_VER >= 1400 // VC 8.0 and later deprecate snprintf and _snprintf. 6141d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot# define snprintf _snprintf_s 6241d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot#elif _MSC_VER 6341d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot# define snprintf _snprintf 6441d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot#endif // GTEST_OS_WINDOWS_MOBILE 6541d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot 6641d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// Prints a segment of bytes in the given object. 6741d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabotvoid PrintByteSegmentInObjectTo(const unsigned char* obj_bytes, size_t start, 6841d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot size_t count, ostream* os) { 6941d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot char text[5] = ""; 7041d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot for (size_t i = 0; i != count; i++) { 7141d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot const size_t j = start + i; 7241d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot if (i != 0) { 7341d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot // Organizes the bytes into groups of 2 for easy parsing by 7441d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot // human. 7541d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot if ((j % 2) == 0) 7641d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot *os << ' '; 7741d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot else 7841d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot *os << '-'; 7941d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot } 8041d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot snprintf(text, sizeof(text), "%02X", obj_bytes[j]); 8141d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot *os << text; 8241d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot } 8341d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot} 8441d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot 8541d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// Prints the bytes in the given value to the given ostream. 8641d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabotvoid PrintBytesInObjectToImpl(const unsigned char* obj_bytes, size_t count, 8741d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot ostream* os) { 8841d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot // Tells the user how big the object is. 8941d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot *os << count << "-byte object <"; 9041d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot 9141d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot const size_t kThreshold = 132; 9241d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot const size_t kChunkSize = 64; 9341d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot // If the object size is bigger than kThreshold, we'll have to omit 9441d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot // some details by printing only the first and the last kChunkSize 9541d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot // bytes. 9641d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot // TODO(wan): let the user control the threshold using a flag. 9741d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot if (count < kThreshold) { 9841d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot PrintByteSegmentInObjectTo(obj_bytes, 0, count, os); 9941d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot } else { 10041d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot PrintByteSegmentInObjectTo(obj_bytes, 0, kChunkSize, os); 10141d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot *os << " ... "; 10241d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot // Rounds up to 2-byte boundary. 10341d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot const size_t resume_pos = (count - kChunkSize + 1)/2*2; 10441d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot PrintByteSegmentInObjectTo(obj_bytes, resume_pos, count - resume_pos, os); 10541d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot } 10641d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot *os << ">"; 10741d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot} 10841d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot 10941d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot} // namespace 11041d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot 11141d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabotnamespace internal2 { 11241d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot 11341d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// Delegates to PrintBytesInObjectToImpl() to print the bytes in the 11441d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// given object. The delegation simplifies the implementation, which 11541d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// uses the << operator and thus is easier done outside of the 11641d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// ::testing::internal namespace, which contains a << operator that 11741d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// sometimes conflicts with the one in STL. 11841d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabotvoid PrintBytesInObjectTo(const unsigned char* obj_bytes, size_t count, 11941d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot ostream* os) { 12041d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot PrintBytesInObjectToImpl(obj_bytes, count, os); 12141d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot} 12241d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot 12341d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot} // namespace internal2 12441d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot 12541d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabotnamespace internal { 12641d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot 12741d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// Depending on the value of a char (or wchar_t), we print it in one 12841d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// of three formats: 12941d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// - as is if it's a printable ASCII (e.g. 'a', '2', ' '), 13041d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// - as a hexidecimal escape sequence (e.g. '\x7F'), or 13141d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// - as a special escape sequence (e.g. '\r', '\n'). 13241d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabotenum CharFormat { 13341d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot kAsIs, 13441d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot kHexEscape, 13541d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot kSpecialEscape 13641d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot}; 13741d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot 13841d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// Returns true if c is a printable ASCII character. We test the 13941d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// value of c directly instead of calling isprint(), which is buggy on 14041d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// Windows Mobile. 14141d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabotinline bool IsPrintableAscii(wchar_t c) { 14241d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot return 0x20 <= c && c <= 0x7E; 14341d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot} 14441d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot 14541d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// Prints a wide or narrow char c as a character literal without the 14641d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// quotes, escaping it when necessary; returns how c was formatted. 14741d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// The template argument UnsignedChar is the unsigned version of Char, 14841d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// which is the type of c. 14941d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabottemplate <typename UnsignedChar, typename Char> 15041d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabotstatic CharFormat PrintAsCharLiteralTo(Char c, ostream* os) { 15141d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot switch (static_cast<wchar_t>(c)) { 15241d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot case L'\0': 15341d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot *os << "\\0"; 15441d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot break; 15541d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot case L'\'': 15641d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot *os << "\\'"; 15741d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot break; 15841d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot case L'\\': 15941d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot *os << "\\\\"; 16041d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot break; 16141d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot case L'\a': 16241d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot *os << "\\a"; 16341d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot break; 16441d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot case L'\b': 16541d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot *os << "\\b"; 16641d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot break; 16741d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot case L'\f': 16841d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot *os << "\\f"; 16941d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot break; 17041d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot case L'\n': 17141d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot *os << "\\n"; 17241d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot break; 17341d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot case L'\r': 17441d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot *os << "\\r"; 17541d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot break; 17641d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot case L'\t': 17741d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot *os << "\\t"; 17841d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot break; 17941d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot case L'\v': 18041d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot *os << "\\v"; 18141d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot break; 18241d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot default: 18341d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot if (IsPrintableAscii(c)) { 18441d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot *os << static_cast<char>(c); 18541d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot return kAsIs; 18641d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot } else { 18741d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot *os << String::Format("\\x%X", static_cast<UnsignedChar>(c)); 18841d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot return kHexEscape; 18941d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot } 19041d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot } 19141d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot return kSpecialEscape; 19241d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot} 19341d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot 19441d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// Prints a char c as if it's part of a string literal, escaping it when 19541d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// necessary; returns how c was formatted. 19641d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabotstatic CharFormat PrintAsWideStringLiteralTo(wchar_t c, ostream* os) { 19741d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot switch (c) { 19841d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot case L'\'': 19941d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot *os << "'"; 20041d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot return kAsIs; 20141d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot case L'"': 20241d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot *os << "\\\""; 20341d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot return kSpecialEscape; 20441d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot default: 20541d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot return PrintAsCharLiteralTo<wchar_t>(c, os); 20641d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot } 20741d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot} 20841d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot 20941d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// Prints a char c as if it's part of a string literal, escaping it when 21041d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// necessary; returns how c was formatted. 21141d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabotstatic CharFormat PrintAsNarrowStringLiteralTo(char c, ostream* os) { 21241d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot return PrintAsWideStringLiteralTo(static_cast<unsigned char>(c), os); 21341d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot} 21441d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot 21541d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// Prints a wide or narrow character c and its code. '\0' is printed 21641d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// as "'\\0'", other unprintable characters are also properly escaped 21741d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// using the standard C++ escape sequence. The template argument 21841d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// UnsignedChar is the unsigned version of Char, which is the type of c. 21941d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabottemplate <typename UnsignedChar, typename Char> 22041d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabotvoid PrintCharAndCodeTo(Char c, ostream* os) { 22141d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot // First, print c as a literal in the most readable form we can find. 22241d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot *os << ((sizeof(c) > 1) ? "L'" : "'"); 22341d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot const CharFormat format = PrintAsCharLiteralTo<UnsignedChar>(c, os); 22441d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot *os << "'"; 22541d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot 22641d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot // To aid user debugging, we also print c's code in decimal, unless 22741d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot // it's 0 (in which case c was printed as '\\0', making the code 22841d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot // obvious). 22941d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot if (c == 0) 23041d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot return; 23141d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot *os << " (" << String::Format("%d", c).c_str(); 23241d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot 23341d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot // For more convenience, we print c's code again in hexidecimal, 23441d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot // unless c was already printed in the form '\x##' or the code is in 23541d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot // [1, 9]. 23641d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot if (format == kHexEscape || (1 <= c && c <= 9)) { 23741d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot // Do nothing. 23841d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot } else { 23941d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot *os << String::Format(", 0x%X", 24041d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot static_cast<UnsignedChar>(c)).c_str(); 24141d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot } 24241d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot *os << ")"; 24341d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot} 24441d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot 24541d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabotvoid PrintTo(unsigned char c, ::std::ostream* os) { 24641d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot PrintCharAndCodeTo<unsigned char>(c, os); 24741d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot} 24841d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabotvoid PrintTo(signed char c, ::std::ostream* os) { 24941d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot PrintCharAndCodeTo<unsigned char>(c, os); 25041d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot} 25141d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot 25241d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// Prints a wchar_t as a symbol if it is printable or as its internal 25341d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// code otherwise and also as its code. L'\0' is printed as "L'\\0'". 25441d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabotvoid PrintTo(wchar_t wc, ostream* os) { 25541d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot PrintCharAndCodeTo<wchar_t>(wc, os); 25641d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot} 25741d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot 25841d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// Prints the given array of characters to the ostream. 25941d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// The array starts at *begin, the length is len, it may include '\0' characters 26041d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// and may not be null-terminated. 26141d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabotstatic void PrintCharsAsStringTo(const char* begin, size_t len, ostream* os) { 26241d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot *os << "\""; 26341d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot bool is_previous_hex = false; 26441d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot for (size_t index = 0; index < len; ++index) { 26541d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot const char cur = begin[index]; 26641d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot if (is_previous_hex && IsXDigit(cur)) { 26741d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot // Previous character is of '\x..' form and this character can be 26841d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot // interpreted as another hexadecimal digit in its number. Break string to 26941d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot // disambiguate. 27041d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot *os << "\" \""; 27141d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot } 27241d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot is_previous_hex = PrintAsNarrowStringLiteralTo(cur, os) == kHexEscape; 27341d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot } 27441d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot *os << "\""; 27541d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot} 27641d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot 27741d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// Prints a (const) char array of 'len' elements, starting at address 'begin'. 27841d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabotvoid UniversalPrintArray(const char* begin, size_t len, ostream* os) { 27941d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot PrintCharsAsStringTo(begin, len, os); 28041d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot} 28141d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot 28241d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// Prints the given array of wide characters to the ostream. 28341d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// The array starts at *begin, the length is len, it may include L'\0' 28441d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// characters and may not be null-terminated. 28541d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabotstatic void PrintWideCharsAsStringTo(const wchar_t* begin, size_t len, 28641d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot ostream* os) { 28741d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot *os << "L\""; 28841d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot bool is_previous_hex = false; 28941d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot for (size_t index = 0; index < len; ++index) { 29041d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot const wchar_t cur = begin[index]; 29141d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot if (is_previous_hex && isascii(cur) && IsXDigit(static_cast<char>(cur))) { 29241d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot // Previous character is of '\x..' form and this character can be 29341d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot // interpreted as another hexadecimal digit in its number. Break string to 29441d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot // disambiguate. 29541d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot *os << "\" L\""; 29641d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot } 29741d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot is_previous_hex = PrintAsWideStringLiteralTo(cur, os) == kHexEscape; 29841d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot } 29941d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot *os << "\""; 30041d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot} 30141d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot 30241d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// Prints the given C string to the ostream. 30341d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabotvoid PrintTo(const char* s, ostream* os) { 30441d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot if (s == NULL) { 30541d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot *os << "NULL"; 30641d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot } else { 30741d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot *os << ImplicitCast_<const void*>(s) << " pointing to "; 30841d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot PrintCharsAsStringTo(s, strlen(s), os); 30941d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot } 31041d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot} 31141d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot 31241d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// MSVC compiler can be configured to define whar_t as a typedef 31341d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// of unsigned short. Defining an overload for const wchar_t* in that case 31441d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// would cause pointers to unsigned shorts be printed as wide strings, 31541d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// possibly accessing more memory than intended and causing invalid 31641d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// memory accesses. MSVC defines _NATIVE_WCHAR_T_DEFINED symbol when 31741d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// wchar_t is implemented as a native type. 31841d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED) 31941d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// Prints the given wide C string to the ostream. 32041d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabotvoid PrintTo(const wchar_t* s, ostream* os) { 32141d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot if (s == NULL) { 32241d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot *os << "NULL"; 32341d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot } else { 32441d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot *os << ImplicitCast_<const void*>(s) << " pointing to "; 32541d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot PrintWideCharsAsStringTo(s, wcslen(s), os); 32641d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot } 32741d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot} 32841d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot#endif // wchar_t is native 32941d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot 33041d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// Prints a ::string object. 33141d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot#if GTEST_HAS_GLOBAL_STRING 33241d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabotvoid PrintStringTo(const ::string& s, ostream* os) { 33341d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot PrintCharsAsStringTo(s.data(), s.size(), os); 33441d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot} 33541d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot#endif // GTEST_HAS_GLOBAL_STRING 33641d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot 33741d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabotvoid PrintStringTo(const ::std::string& s, ostream* os) { 33841d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot PrintCharsAsStringTo(s.data(), s.size(), os); 33941d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot} 34041d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot 34141d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// Prints a ::wstring object. 34241d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot#if GTEST_HAS_GLOBAL_WSTRING 34341d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabotvoid PrintWideStringTo(const ::wstring& s, ostream* os) { 34441d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot PrintWideCharsAsStringTo(s.data(), s.size(), os); 34541d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot} 34641d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot#endif // GTEST_HAS_GLOBAL_WSTRING 34741d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot 34841d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot#if GTEST_HAS_STD_WSTRING 34941d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabotvoid PrintWideStringTo(const ::std::wstring& s, ostream* os) { 35041d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot PrintWideCharsAsStringTo(s.data(), s.size(), os); 35141d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot} 35241d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot#endif // GTEST_HAS_STD_WSTRING 35341d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot 35441d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot} // namespace internal 35541d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot 35641d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot} // namespace testing 357