gtest-printers.cc revision fc2de66453b0669c09eaca643b07d34443858b6f
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright 2007, Google Inc. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// All rights reserved. 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Redistribution and use in source and binary forms, with or without 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// modification, are permitted provided that the following conditions are 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// met: 7eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// 8ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// * Redistributions of source code must retain the above copyright 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// notice, this list of conditions and the following disclaimer. 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// * Redistributions in binary form must reproduce the above 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// copyright notice, this list of conditions and the following disclaimer 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// in the documentation and/or other materials provided with the 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// distribution. 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// * Neither the name of Google Inc. nor the names of its 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// contributors may be used to endorse or promote products derived from 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// this software without specific prior written permission. 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Author: wan@google.com (Zhanyong Wan) 313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// Google Test - The Google C++ Testing Framework 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This file implements a universal value printer that can print a 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// value of any type T: 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 37eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// void ::testing::internal::UniversalPrinter<T>::Print(value, ostream_ptr); 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// It uses the << operator when possible, and prints the bytes in the 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// object otherwise. A user can override its behavior for a class 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// type Foo by defining either operator<<(::std::ostream&, const Foo&) 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// or void PrintTo(const Foo&, ::std::ostream*) in the namespace that 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// defines Foo. 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "gtest/gtest-printers.h" 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <ctype.h> 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <stdio.h> 48ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include <ostream> // NOLINT 49ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include <string> 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "gtest/internal/gtest-port.h" 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace testing { 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace { 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using ::std::ostream; 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Prints a segment of bytes in the given object. 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void PrintByteSegmentInObjectTo(const unsigned char* obj_bytes, size_t start, 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_t count, ostream* os) { 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) char text[5] = ""; 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i != count; i++) { 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const size_t j = start + i; 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (i != 0) { 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Organizes the bytes into groups of 2 for easy parsing by 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // human. 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((j % 2) == 0) 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *os << ' '; 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *os << '-'; 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GTEST_SNPRINTF_(text, sizeof(text), "%02X", obj_bytes[j]); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *os << text; 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Prints the bytes in the given value to the given ostream. 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PrintBytesInObjectToImpl(const unsigned char* obj_bytes, size_t count, 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ostream* os) { 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Tells the user how big the object is. 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *os << count << "-byte object <"; 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const size_t kThreshold = 132; 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const size_t kChunkSize = 64; 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the object size is bigger than kThreshold, we'll have to omit 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // some details by printing only the first and the last kChunkSize 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // bytes. 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(wan): let the user control the threshold using a flag. 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (count < kThreshold) { 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrintByteSegmentInObjectTo(obj_bytes, 0, count, os); 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PrintByteSegmentInObjectTo(obj_bytes, 0, kChunkSize, os); 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *os << " ... "; 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Rounds up to 2-byte boundary. 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const size_t resume_pos = (count - kChunkSize + 1)/2*2; 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PrintByteSegmentInObjectTo(obj_bytes, resume_pos, count - resume_pos, os); 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *os << ">"; 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace internal2 { 104eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Delegates to PrintBytesInObjectToImpl() to print the bytes in the 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// given object. The delegation simplifies the implementation, which 107eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// uses the << operator and thus is easier done outside of the 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ::testing::internal namespace, which contains a << operator that 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// sometimes conflicts with the one in STL. 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PrintBytesInObjectTo(const unsigned char* obj_bytes, size_t count, 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ostream* os) { 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrintBytesInObjectToImpl(obj_bytes, count, os); 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace internal2 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace internal { 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Depending on the value of a char (or wchar_t), we print it in one 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// of three formats: 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// - as is if it's a printable ASCII (e.g. 'a', '2', ' '), 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// - as a hexidecimal escape sequence (e.g. '\x7F'), or 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// - as a special escape sequence (e.g. '\r', '\n'). 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)enum CharFormat { 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) kAsIs, 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) kHexEscape, 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) kSpecialEscape 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns true if c is a printable ASCII character. We test the 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// value of c directly instead of calling isprint(), which is buggy on 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Windows Mobile. 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline bool IsPrintableAscii(wchar_t c) { 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0x20 <= c && c <= 0x7E; 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Prints a wide or narrow char c as a character literal without the 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// quotes, escaping it when necessary; returns how c was formatted. 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The template argument UnsignedChar is the unsigned version of Char, 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// which is the type of c. 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename UnsignedChar, typename Char> 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static CharFormat PrintAsCharLiteralTo(Char c, ostream* os) { 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (static_cast<wchar_t>(c)) { 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case L'\0': 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *os << "\\0"; 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case L'\'': 1483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) *os << "\\'"; 1493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) break; 1503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case L'\\': 1513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) *os << "\\\\"; 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case L'\a': 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *os << "\\a"; 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case L'\b': 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *os << "\\b"; 1583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) break; 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case L'\f': 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *os << "\\f"; 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case L'\n': 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *os << "\\n"; 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case L'\r': 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *os << "\\r"; 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case L'\t': 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *os << "\\t"; 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case L'\v': 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *os << "\\v"; 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) default: 17590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (IsPrintableAscii(c)) { 17690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) *os << static_cast<char>(c); 17790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return kAsIs; 17890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } else { 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *os << "\\x" + String::FormatHexInt(static_cast<UnsignedChar>(c)); 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return kHexEscape; 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return kSpecialEscape; 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Prints a wchar_t c as if it's part of a string literal, escaping it when 1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// necessary; returns how c was formatted. 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static CharFormat PrintAsStringLiteralTo(wchar_t c, ostream* os) { 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switch (c) { 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case L'\'': 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *os << "'"; 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return kAsIs; 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case L'"': 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *os << "\\\""; 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return kSpecialEscape; 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) default: 1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return PrintAsCharLiteralTo<wchar_t>(c, os); 1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Prints a char c as if it's part of a string literal, escaping it when 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// necessary; returns how c was formatted. 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static CharFormat PrintAsStringLiteralTo(char c, ostream* os) { 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PrintAsStringLiteralTo( 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<wchar_t>(static_cast<unsigned char>(c)), os); 2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Prints a wide or narrow character c and its code. '\0' is printed 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// as "'\\0'", other unprintable characters are also properly escaped 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// using the standard C++ escape sequence. The template argument 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// UnsignedChar is the unsigned version of Char, which is the type of c. 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename UnsignedChar, typename Char> 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PrintCharAndCodeTo(Char c, ostream* os) { 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // First, print c as a literal in the most readable form we can find. 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *os << ((sizeof(c) > 1) ? "L'" : "'"); 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const CharFormat format = PrintAsCharLiteralTo<UnsignedChar>(c, os); 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *os << "'"; 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // To aid user debugging, we also print c's code in decimal, unless 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // it's 0 (in which case c was printed as '\\0', making the code 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // obvious). 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (c == 0) 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *os << " (" << static_cast<int>(c); 2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For more convenience, we print c's code again in hexidecimal, 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // unless c was already printed in the form '\x##' or the code is in 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // [1, 9]. 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (format == kHexEscape || (1 <= c && c <= 9)) { 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Do nothing. 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *os << ", 0x" << String::FormatHexInt(static_cast<UnsignedChar>(c)); 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *os << ")"; 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PrintTo(unsigned char c, ::std::ostream* os) { 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrintCharAndCodeTo<unsigned char>(c, os); 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PrintTo(signed char c, ::std::ostream* os) { 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrintCharAndCodeTo<unsigned char>(c, os); 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Prints a wchar_t as a symbol if it is printable or as its internal 2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// code otherwise and also as its code. L'\0' is printed as "L'\\0'". 2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void PrintTo(wchar_t wc, ostream* os) { 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrintCharAndCodeTo<wchar_t>(wc, os); 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Prints the given array of characters to the ostream. CharType must be either 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// char or wchar_t. 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The array starts at begin, the length is len, it may include '\0' characters 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// and may not be NUL-terminated. 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename CharType> 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void PrintCharsAsStringTo( 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const CharType* begin, size_t len, ostream* os) { 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* const kQuoteBegin = sizeof(CharType) == 1 ? "\"" : "L\""; 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *os << kQuoteBegin; 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_previous_hex = false; 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t index = 0; index < len; ++index) { 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const CharType cur = begin[index]; 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (is_previous_hex && IsXDigit(cur)) { 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Previous character is of '\x..' form and this character can be 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // interpreted as another hexadecimal digit in its number. Break string to 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // disambiguate. 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *os << "\" " << kQuoteBegin; 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_previous_hex = PrintAsStringLiteralTo(cur, os) == kHexEscape; 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *os << "\""; 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Prints a (const) char/wchar_t array of 'len' elements, starting at address 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 'begin'. CharType must be either char or wchar_t. 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename CharType> 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void UniversalPrintCharArray( 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const CharType* begin, size_t len, ostream* os) { 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The code 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // const char kFoo[] = "foo"; 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // generates an array of 4, not 3, elements, with the last one being '\0'. 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Therefore when printing a char array, we don't print the last element if 283c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // it's '\0', such that the output matches the string literal as it's 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // written in the source code. 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (len > 0 && begin[len - 1] == '\0') { 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrintCharsAsStringTo(begin, len - 1, os); 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If, however, the last element in the array is not '\0', e.g. 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // const char kFoo[] = { 'f', 'o', 'o' }; 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // we must print the entire array. We also print a message to indicate 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // that the array is not NUL-terminated. 2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PrintCharsAsStringTo(begin, len, os); 2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *os << " (no terminating NUL)"; 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Prints a (const) char array of 'len' elements, starting at address 'begin'. 2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void UniversalPrintArray(const char* begin, size_t len, ostream* os) { 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UniversalPrintCharArray(begin, len, os); 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Prints a (const) wchar_t array of 'len' elements, starting at address 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 'begin'. 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void UniversalPrintArray(const wchar_t* begin, size_t len, ostream* os) { 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UniversalPrintCharArray(begin, len, os); 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Prints the given C string to the ostream. 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PrintTo(const char* s, ostream* os) { 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (s == NULL) { 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *os << "NULL"; 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *os << ImplicitCast_<const void*>(s) << " pointing to "; 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrintCharsAsStringTo(s, strlen(s), os); 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// MSVC compiler can be configured to define whar_t as a typedef 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// of unsigned short. Defining an overload for const wchar_t* in that case 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// would cause pointers to unsigned shorts be printed as wide strings, 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// possibly accessing more memory than intended and causing invalid 3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// memory accesses. MSVC defines _NATIVE_WCHAR_T_DEFINED symbol when 3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// wchar_t is implemented as a native type. 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED) 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Prints the given wide C string to the ostream. 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PrintTo(const wchar_t* s, ostream* os) { 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (s == NULL) { 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *os << "NULL"; 3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *os << ImplicitCast_<const void*>(s) << " pointing to "; 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrintCharsAsStringTo(s, wcslen(s), os); 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // wchar_t is native 336c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 337c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Prints a ::string object. 338c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#if GTEST_HAS_GLOBAL_STRING 339c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void PrintStringTo(const ::string& s, ostream* os) { 340c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) PrintCharsAsStringTo(s.data(), s.size(), os); 341c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 342c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif // GTEST_HAS_GLOBAL_STRING 343c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 344c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void PrintStringTo(const ::std::string& s, ostream* os) { 345c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) PrintCharsAsStringTo(s.data(), s.size(), os); 346c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 347c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 348c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Prints a ::wstring object. 349c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#if GTEST_HAS_GLOBAL_WSTRING 350c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void PrintWideStringTo(const ::wstring& s, ostream* os) { 351c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) PrintCharsAsStringTo(s.data(), s.size(), os); 352c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 353c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif // GTEST_HAS_GLOBAL_WSTRING 354c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 355c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#if GTEST_HAS_STD_WSTRING 356c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void PrintWideStringTo(const ::std::wstring& s, ostream* os) { 357c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) PrintCharsAsStringTo(s.data(), s.size(), os); 358} 359#endif // GTEST_HAS_STD_WSTRING 360 361} // namespace internal 362 363} // namespace testing 364