Makes gtest print string literals correctly when it contains \x escape sequences. Contributed by Yair Chuchem.
This commit is contained in:
parent
42bf979ce7
commit
b5eb6ed9e2
|
@ -1462,6 +1462,9 @@ inline bool IsSpace(char ch) {
|
||||||
inline bool IsUpper(char ch) {
|
inline bool IsUpper(char ch) {
|
||||||
return isupper(static_cast<unsigned char>(ch)) != 0;
|
return isupper(static_cast<unsigned char>(ch)) != 0;
|
||||||
}
|
}
|
||||||
|
inline bool IsXDigit(char ch) {
|
||||||
|
return isxdigit(static_cast<unsigned char>(ch)) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
inline char ToLower(char ch) {
|
inline char ToLower(char ch) {
|
||||||
return static_cast<char>(tolower(static_cast<unsigned char>(ch)));
|
return static_cast<char>(tolower(static_cast<unsigned char>(ch)));
|
||||||
|
|
|
@ -194,25 +194,25 @@ static CharFormat PrintAsCharLiteralTo(Char c, ostream* os) {
|
||||||
return kSpecialEscape;
|
return kSpecialEscape;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prints a char as if it's part of a string literal, escaping it when
|
// Prints a char c as if it's part of a string literal, escaping it when
|
||||||
// necessary.
|
// necessary; returns how c was formatted.
|
||||||
static void PrintAsWideStringLiteralTo(wchar_t c, ostream* os) {
|
static CharFormat PrintAsWideStringLiteralTo(wchar_t c, ostream* os) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case L'\'':
|
case L'\'':
|
||||||
*os << "'";
|
*os << "'";
|
||||||
break;
|
return kAsIs;
|
||||||
case L'"':
|
case L'"':
|
||||||
*os << "\\\"";
|
*os << "\\\"";
|
||||||
break;
|
return kSpecialEscape;
|
||||||
default:
|
default:
|
||||||
PrintAsCharLiteralTo<wchar_t>(c, os);
|
return PrintAsCharLiteralTo<wchar_t>(c, os);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prints a char as if it's part of a string literal, escaping it when
|
// Prints a char c as if it's part of a string literal, escaping it when
|
||||||
// necessary.
|
// necessary; returns how c was formatted.
|
||||||
static void PrintAsNarrowStringLiteralTo(char c, ostream* os) {
|
static CharFormat PrintAsNarrowStringLiteralTo(char c, ostream* os) {
|
||||||
PrintAsWideStringLiteralTo(static_cast<unsigned char>(c), os);
|
return PrintAsWideStringLiteralTo(static_cast<unsigned char>(c), os);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prints a wide or narrow character c and its code. '\0' is printed
|
// Prints a wide or narrow character c and its code. '\0' is printed
|
||||||
|
@ -263,8 +263,16 @@ void PrintTo(wchar_t wc, ostream* os) {
|
||||||
// and may not be null-terminated.
|
// and may not be null-terminated.
|
||||||
static void PrintCharsAsStringTo(const char* begin, size_t len, ostream* os) {
|
static void PrintCharsAsStringTo(const char* begin, size_t len, ostream* os) {
|
||||||
*os << "\"";
|
*os << "\"";
|
||||||
|
bool is_previous_hex = false;
|
||||||
for (size_t index = 0; index < len; ++index) {
|
for (size_t index = 0; index < len; ++index) {
|
||||||
PrintAsNarrowStringLiteralTo(begin[index], os);
|
const char 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 << "\" \"";
|
||||||
|
}
|
||||||
|
is_previous_hex = PrintAsNarrowStringLiteralTo(cur, os) == kHexEscape;
|
||||||
}
|
}
|
||||||
*os << "\"";
|
*os << "\"";
|
||||||
}
|
}
|
||||||
|
@ -280,8 +288,17 @@ void UniversalPrintArray(const char* begin, size_t len, ostream* os) {
|
||||||
static void PrintWideCharsAsStringTo(const wchar_t* begin, size_t len,
|
static void PrintWideCharsAsStringTo(const wchar_t* begin, size_t len,
|
||||||
ostream* os) {
|
ostream* os) {
|
||||||
*os << "L\"";
|
*os << "L\"";
|
||||||
|
bool is_previous_hex = false;
|
||||||
for (size_t index = 0; index < len; ++index) {
|
for (size_t index = 0; index < len; ++index) {
|
||||||
PrintAsWideStringLiteralTo(begin[index], os);
|
const wchar_t cur = begin[index];
|
||||||
|
if (is_previous_hex && 0 <= cur && cur < 128 &&
|
||||||
|
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 << "\"";
|
*os << "\"";
|
||||||
}
|
}
|
||||||
|
|
|
@ -658,6 +658,20 @@ TEST(PrintStringTest, StringInStdNamespace) {
|
||||||
Print(str));
|
Print(str));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(PrintStringTest, StringAmbiguousHex) {
|
||||||
|
// "\x6BANANA" is ambiguous, it can be interpreted as starting with either of:
|
||||||
|
// '\x6', '\x6B', or '\x6BA'.
|
||||||
|
|
||||||
|
// a hex escaping sequence following by a decimal digit
|
||||||
|
EXPECT_EQ("\"0\\x12\" \"3\"", Print(::std::string("0\x12" "3")));
|
||||||
|
// a hex escaping sequence following by a hex digit (lower-case)
|
||||||
|
EXPECT_EQ("\"mm\\x6\" \"bananas\"", Print(::std::string("mm\x6" "bananas")));
|
||||||
|
// a hex escaping sequence following by a hex digit (upper-case)
|
||||||
|
EXPECT_EQ("\"NOM\\x6\" \"BANANA\"", Print(::std::string("NOM\x6" "BANANA")));
|
||||||
|
// a hex escaping sequence following by a non-xdigit
|
||||||
|
EXPECT_EQ("\"!\\x5-!\"", Print(::std::string("!\x5-!")));
|
||||||
|
}
|
||||||
|
|
||||||
// Tests printing ::wstring and ::std::wstring.
|
// Tests printing ::wstring and ::std::wstring.
|
||||||
|
|
||||||
#if GTEST_HAS_GLOBAL_WSTRING
|
#if GTEST_HAS_GLOBAL_WSTRING
|
||||||
|
@ -680,6 +694,16 @@ TEST(PrintWideStringTest, StringInStdNamespace) {
|
||||||
"\\xD3\\x576\\x8D3\\xC74D a\\0\"",
|
"\\xD3\\x576\\x8D3\\xC74D a\\0\"",
|
||||||
Print(str));
|
Print(str));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(PrintWideStringTest, StringAmbiguousHex) {
|
||||||
|
// same for wide strings.
|
||||||
|
EXPECT_EQ("L\"0\\x12\" L\"3\"", Print(::std::wstring(L"0\x12" L"3")));
|
||||||
|
EXPECT_EQ("L\"mm\\x6\" L\"bananas\"",
|
||||||
|
Print(::std::wstring(L"mm\x6" L"bananas")));
|
||||||
|
EXPECT_EQ("L\"NOM\\x6\" L\"BANANA\"",
|
||||||
|
Print(::std::wstring(L"NOM\x6" L"BANANA")));
|
||||||
|
EXPECT_EQ("L\"!\\x5-!\"", Print(::std::wstring(L"!\x5-!")));
|
||||||
|
}
|
||||||
#endif // GTEST_HAS_STD_WSTRING
|
#endif // GTEST_HAS_STD_WSTRING
|
||||||
|
|
||||||
// Tests printing types that support generic streaming (i.e. streaming
|
// Tests printing types that support generic streaming (i.e. streaming
|
||||||
|
|
Loading…
Reference in New Issue
Block a user