Improves gtest's failure messages. In particulars, char pointers and
char arrays are not escapped properly.
This commit is contained in:
@@ -183,9 +183,9 @@ static CharFormat PrintAsCharLiteralTo(Char c, ostream* os) {
|
||||
return kSpecialEscape;
|
||||
}
|
||||
|
||||
// Prints a char c as if it's part of a string literal, escaping it when
|
||||
// Prints a wchar_t c as if it's part of a string literal, escaping it when
|
||||
// necessary; returns how c was formatted.
|
||||
static CharFormat PrintAsWideStringLiteralTo(wchar_t c, ostream* os) {
|
||||
static CharFormat PrintAsStringLiteralTo(wchar_t c, ostream* os) {
|
||||
switch (c) {
|
||||
case L'\'':
|
||||
*os << "'";
|
||||
@@ -200,8 +200,9 @@ static CharFormat PrintAsWideStringLiteralTo(wchar_t c, ostream* os) {
|
||||
|
||||
// Prints a char c as if it's part of a string literal, escaping it when
|
||||
// necessary; returns how c was formatted.
|
||||
static CharFormat PrintAsNarrowStringLiteralTo(char c, ostream* os) {
|
||||
return PrintAsWideStringLiteralTo(static_cast<unsigned char>(c), os);
|
||||
static CharFormat PrintAsStringLiteralTo(char c, ostream* os) {
|
||||
return PrintAsStringLiteralTo(
|
||||
static_cast<wchar_t>(static_cast<unsigned char>(c)), os);
|
||||
}
|
||||
|
||||
// Prints a wide or narrow character c and its code. '\0' is printed
|
||||
@@ -247,48 +248,63 @@ void PrintTo(wchar_t wc, ostream* os) {
|
||||
PrintCharAndCodeTo<wchar_t>(wc, os);
|
||||
}
|
||||
|
||||
// Prints the given array of characters to the ostream.
|
||||
// The array starts at *begin, the length is len, it may include '\0' characters
|
||||
// and may not be null-terminated.
|
||||
static void PrintCharsAsStringTo(const char* begin, size_t len, ostream* os) {
|
||||
*os << "\"";
|
||||
// Prints the given array of characters to the ostream. CharType must be either
|
||||
// char or wchar_t.
|
||||
// The array starts at begin, the length is len, it may include '\0' characters
|
||||
// and may not be NUL-terminated.
|
||||
template <typename CharType>
|
||||
static void PrintCharsAsStringTo(
|
||||
const CharType* begin, size_t len, ostream* os) {
|
||||
const char* const kQuoteBegin = sizeof(CharType) == 1 ? "\"" : "L\"";
|
||||
*os << kQuoteBegin;
|
||||
bool is_previous_hex = false;
|
||||
for (size_t index = 0; index < len; ++index) {
|
||||
const char cur = begin[index];
|
||||
const CharType cur = begin[index];
|
||||
if (is_previous_hex && IsXDigit(cur)) {
|
||||
// Previous character is of '\x..' form and this character can be
|
||||
// interpreted as another hexadecimal digit in its number. Break string to
|
||||
// disambiguate.
|
||||
*os << "\" \"";
|
||||
*os << "\" " << kQuoteBegin;
|
||||
}
|
||||
is_previous_hex = PrintAsNarrowStringLiteralTo(cur, os) == kHexEscape;
|
||||
is_previous_hex = PrintAsStringLiteralTo(cur, os) == kHexEscape;
|
||||
}
|
||||
*os << "\"";
|
||||
}
|
||||
|
||||
// Prints a (const) char/wchar_t array of 'len' elements, starting at address
|
||||
// 'begin'. CharType must be either char or wchar_t.
|
||||
template <typename CharType>
|
||||
static void UniversalPrintCharArray(
|
||||
const CharType* begin, size_t len, ostream* os) {
|
||||
// The code
|
||||
// const char kFoo[] = "foo";
|
||||
// generates an array of 4, not 3, elements, with the last one being '\0'.
|
||||
//
|
||||
// Therefore when printing a char array, we don't print the last element if
|
||||
// it's '\0', such that the output matches the string literal as it's
|
||||
// written in the source code.
|
||||
if (len > 0 && begin[len - 1] == '\0') {
|
||||
PrintCharsAsStringTo(begin, len - 1, os);
|
||||
return;
|
||||
}
|
||||
|
||||
// If, however, the last element in the array is not '\0', e.g.
|
||||
// const char kFoo[] = { 'f', 'o', 'o' };
|
||||
// we must print the entire array. We also print a message to indicate
|
||||
// that the array is not NUL-terminated.
|
||||
PrintCharsAsStringTo(begin, len, os);
|
||||
*os << " (no terminating NUL)";
|
||||
}
|
||||
|
||||
// Prints a (const) char array of 'len' elements, starting at address 'begin'.
|
||||
void UniversalPrintArray(const char* begin, size_t len, ostream* os) {
|
||||
PrintCharsAsStringTo(begin, len, os);
|
||||
UniversalPrintCharArray(begin, len, os);
|
||||
}
|
||||
|
||||
// Prints the given array of wide characters to the ostream.
|
||||
// The array starts at *begin, the length is len, it may include L'\0'
|
||||
// characters and may not be null-terminated.
|
||||
static void PrintWideCharsAsStringTo(const wchar_t* begin, size_t len,
|
||||
ostream* os) {
|
||||
*os << "L\"";
|
||||
bool is_previous_hex = false;
|
||||
for (size_t index = 0; index < len; ++index) {
|
||||
const wchar_t cur = begin[index];
|
||||
if (is_previous_hex && isascii(cur) && IsXDigit(static_cast<char>(cur))) {
|
||||
// Previous character is of '\x..' form and this character can be
|
||||
// interpreted as another hexadecimal digit in its number. Break string to
|
||||
// disambiguate.
|
||||
*os << "\" L\"";
|
||||
}
|
||||
is_previous_hex = PrintAsWideStringLiteralTo(cur, os) == kHexEscape;
|
||||
}
|
||||
*os << "\"";
|
||||
// Prints a (const) wchar_t array of 'len' elements, starting at address
|
||||
// 'begin'.
|
||||
void UniversalPrintArray(const wchar_t* begin, size_t len, ostream* os) {
|
||||
UniversalPrintCharArray(begin, len, os);
|
||||
}
|
||||
|
||||
// Prints the given C string to the ostream.
|
||||
@@ -314,7 +330,7 @@ void PrintTo(const wchar_t* s, ostream* os) {
|
||||
*os << "NULL";
|
||||
} else {
|
||||
*os << ImplicitCast_<const void*>(s) << " pointing to ";
|
||||
PrintWideCharsAsStringTo(s, wcslen(s), os);
|
||||
PrintCharsAsStringTo(s, wcslen(s), os);
|
||||
}
|
||||
}
|
||||
#endif // wchar_t is native
|
||||
@@ -333,13 +349,13 @@ void PrintStringTo(const ::std::string& s, ostream* os) {
|
||||
// Prints a ::wstring object.
|
||||
#if GTEST_HAS_GLOBAL_WSTRING
|
||||
void PrintWideStringTo(const ::wstring& s, ostream* os) {
|
||||
PrintWideCharsAsStringTo(s.data(), s.size(), os);
|
||||
PrintCharsAsStringTo(s.data(), s.size(), os);
|
||||
}
|
||||
#endif // GTEST_HAS_GLOBAL_WSTRING
|
||||
|
||||
#if GTEST_HAS_STD_WSTRING
|
||||
void PrintWideStringTo(const ::std::wstring& s, ostream* os) {
|
||||
PrintWideCharsAsStringTo(s.data(), s.size(), os);
|
||||
PrintCharsAsStringTo(s.data(), s.size(), os);
|
||||
}
|
||||
#endif // GTEST_HAS_STD_WSTRING
|
||||
|
||||
|
||||
Reference in New Issue
Block a user