forked from OSchip/llvm-project
Support escapes and quotes in string and character values.
Summary: Escape characters in strings and strings containing quotes were not appearing correctly in expression values. Patch from paulmay@microsoft.com Reviewers: abidh, ChuckR, paulmaybee Subscribers: greggm, lldb-commits Differential Revision: http://reviews.llvm.org/D11371 llvm-svn: 243383
This commit is contained in:
parent
0a674401bf
commit
b56c50f0ec
|
@ -37,27 +37,27 @@ class MiGdbSetShowTestCase(lldbmi_testcase.MiTestCaseBase):
|
|||
|
||||
# Test that an char* is expanded to string when print char-array-as-string is "off"
|
||||
self.runCmd("-var-create - * cp")
|
||||
self.expect("\^done,name=\"var\d+\",numchild=\"1\",value=\"0x[0-9a-f]+ \\\\\\\"hello\\\\\\\"\",type=\"const char \*\",thread-id=\"1\",has_more=\"0\"")
|
||||
self.expect("\^done,name=\"var\d+\",numchild=\"1\",value=\"0x[0-9a-f]+ \\\\\\\"\\\\\\\\t\\\\\\\\\\\\\"hello\\\\\\\\\\\\\"\\\\\\\\n\\\\\\\"\",type=\"const char \*\",thread-id=\"1\",has_more=\"0\"")
|
||||
|
||||
# Test that an char[] isn't expanded to string when print char-array-as-string is "off"
|
||||
self.runCmd("-var-create - * ca")
|
||||
self.expect("\^done,name=\"var\d+\",numchild=\"6\",value=\"\[6\]\",type=\"const char \[6\]\",thread-id=\"1\",has_more=\"0\"")
|
||||
self.expect("\^done,name=\"var\d+\",numchild=\"10\",value=\"\[10\]\",type=\"const char \[10\]\",thread-id=\"1\",has_more=\"0\"")
|
||||
|
||||
# Test that an char16_t* is expanded to string when print char-array-as-string is "off"
|
||||
self.runCmd("-var-create - * u16p")
|
||||
self.expect("\^done,name=\"var\d+\",numchild=\"1\",value=\"0x[0-9a-f]+ u\\\\\\\"hello\\\\\\\"\",type=\"const char16_t \*\",thread-id=\"1\",has_more=\"0\"")
|
||||
self.expect("\^done,name=\"var\d+\",numchild=\"1\",value=\"0x[0-9a-f]+ u\\\\\\\"\\\\\\\\t\\\\\\\\\\\\\"hello\\\\\\\\\\\\\"\\\\\\\\n\\\\\\\"\",type=\"const char16_t \*\",thread-id=\"1\",has_more=\"0\"")
|
||||
|
||||
# Test that an char16_t[] isn't expanded to string when print char-array-as-string is "off"
|
||||
self.runCmd("-var-create - * u16a")
|
||||
self.expect("\^done,name=\"var\d+\",numchild=\"6\",value=\"\[6\]\",type=\"const char16_t \[6\]\",thread-id=\"1\",has_more=\"0\"")
|
||||
self.expect("\^done,name=\"var\d+\",numchild=\"10\",value=\"\[10\]\",type=\"const char16_t \[10\]\",thread-id=\"1\",has_more=\"0\"")
|
||||
|
||||
# Test that an char32_t* is expanded to string when print char-array-as-string is "off"
|
||||
self.runCmd("-var-create - * u32p")
|
||||
self.expect("\^done,name=\"var\d+\",numchild=\"1\",value=\"0x[0-9a-f]+ U\\\\\\\"hello\\\\\\\"\",type=\"const char32_t \*\",thread-id=\"1\",has_more=\"0\"")
|
||||
self.expect("\^done,name=\"var\d+\",numchild=\"1\",value=\"0x[0-9a-f]+ U\\\\\\\"\\\\\\\\t\\\\\\\\\\\\\"hello\\\\\\\\\\\\\"\\\\\\\\n\\\\\\\"\",type=\"const char32_t \*\",thread-id=\"1\",has_more=\"0\"")
|
||||
|
||||
# Test that an char32_t[] isn't expanded to string when print char-array-as-string is "off"
|
||||
self.runCmd("-var-create - * u32a")
|
||||
self.expect("\^done,name=\"var\d+\",numchild=\"6\",value=\"\[6\]\",type=\"const char32_t \[6\]\",thread-id=\"1\",has_more=\"0\"")
|
||||
self.expect("\^done,name=\"var\d+\",numchild=\"10\",value=\"\[10\]\",type=\"const char32_t \[10\]\",thread-id=\"1\",has_more=\"0\"")
|
||||
|
||||
# Test that -gdb-set can set print char-array-as-string flag
|
||||
self.runCmd("-gdb-set print char-array-as-string on")
|
||||
|
@ -67,29 +67,29 @@ class MiGdbSetShowTestCase(lldbmi_testcase.MiTestCaseBase):
|
|||
self.runCmd("-gdb-show print char-array-as-string")
|
||||
self.expect("\^done,value=\"on\"")
|
||||
|
||||
# Test that an char* is expanded to string when print char-array-as-string is "on"
|
||||
# Test that an char* with escape chars is expanded to string when print char-array-as-string is "on"
|
||||
self.runCmd("-var-create - * cp")
|
||||
self.expect("\^done,name=\"var\d+\",numchild=\"1\",value=\"0x[0-9a-f]+ \\\\\\\"hello\\\\\\\"\",type=\"const char \*\",thread-id=\"1\",has_more=\"0\"")
|
||||
|
||||
# Test that an char[] isn't expanded to string when print char-array-as-string is "on"
|
||||
self.expect("\^done,name=\"var\d+\",numchild=\"1\",value=\"0x[0-9a-f]+ \\\\\\\"\\\\\\\\t\\\\\\\\\\\\\"hello\\\\\\\\\\\\\"\\\\\\\\n\\\\\\\"\",type=\"const char \*\",thread-id=\"1\",has_more=\"0\"")
|
||||
|
||||
# Test that an char[] with escape chars is expanded to string when print char-array-as-string is "on"
|
||||
self.runCmd("-var-create - * ca")
|
||||
self.expect("\^done,name=\"var\d+\",numchild=\"6\",value=\"\\\\\\\"hello\\\\\\\"\",type=\"const char \[6\]\",thread-id=\"1\",has_more=\"0\"")
|
||||
|
||||
# Test that an char16_t* is expanded to string when print char-array-as-string is "on"
|
||||
self.expect("\^done,name=\"var\d+\",numchild=\"10\",value=\"\\\\\\\"\\\\\\\\t\\\\\\\\\\\\\"hello\\\\\\\\\\\\\"\\\\\\\\n\\\\\\\"\",type=\"const char \[10\]\",thread-id=\"1\",has_more=\"0\"")
|
||||
|
||||
# Test that an char16_t* with esc1ape chars is expanded to string when print char-array-as-string is "on"
|
||||
self.runCmd("-var-create - * u16p")
|
||||
self.expect("\^done,name=\"var\d+\",numchild=\"1\",value=\"0x[0-9a-f]+ u\\\\\\\"hello\\\\\\\"\",type=\"const char16_t \*\",thread-id=\"1\",has_more=\"0\"")
|
||||
|
||||
# Test that an char16_t[] isn't expanded to string when print char-array-as-string is "on"
|
||||
self.expect("\^done,name=\"var\d+\",numchild=\"1\",value=\"0x[0-9a-f]+ u\\\\\\\"\\\\\\\\t\\\\\\\\\\\\\"hello\\\\\\\\\\\\\"\\\\\\\\n\\\\\\\"\",type=\"const char16_t \*\",thread-id=\"1\",has_more=\"0\"")
|
||||
|
||||
# Test that an char16_t[] with escape chars is expanded to string when print char-array-as-string is "on"
|
||||
self.runCmd("-var-create - * u16a")
|
||||
self.expect("\^done,name=\"var\d+\",numchild=\"6\",value=\"u\\\\\\\"hello\\\\\\\"\",type=\"const char16_t \[6\]\",thread-id=\"1\",has_more=\"0\"")
|
||||
|
||||
# Test that an char32_t* is expanded to string when print char-array-as-string is "on"
|
||||
self.expect("\^done,name=\"var\d+\",numchild=\"10\",value=\"u\\\\\\\"\\\\\\\\t\\\\\\\\\\\\\"hello\\\\\\\\\\\\\"\\\\\\\\n\\\\\\\"\",type=\"const char16_t \[10\]\",thread-id=\"1\",has_more=\"0\"")
|
||||
|
||||
# Test that an char32_t* with escape chars is expanded to string when print char-array-as-string is "on"
|
||||
self.runCmd("-var-create - * u32p")
|
||||
self.expect("\^done,name=\"var\d+\",numchild=\"1\",value=\"0x[0-9a-f]+ U\\\\\\\"hello\\\\\\\"\",type=\"const char32_t \*\",thread-id=\"1\",has_more=\"0\"")
|
||||
|
||||
# Test that an char32_t[] isn't expanded to string when print char-array-as-string is "on"
|
||||
self.expect("\^done,name=\"var\d+\",numchild=\"1\",value=\"0x[0-9a-f]+ U\\\\\\\"\\\\\\\\t\\\\\\\\\\\\\"hello\\\\\\\\\\\\\"\\\\\\\\n\\\\\\\"\",type=\"const char32_t \*\",thread-id=\"1\",has_more=\"0\"")
|
||||
|
||||
# Test that an char32_t[] with escape chars is expanded to string when print char-array-as-string is "on"
|
||||
self.runCmd("-var-create - * u32a")
|
||||
self.expect("\^done,name=\"var\d+\",numchild=\"6\",value=\"U\\\\\\\"hello\\\\\\\"\",type=\"const char32_t \[6\]\",thread-id=\"1\",has_more=\"0\"")
|
||||
self.expect("\^done,name=\"var\d+\",numchild=\"10\",value=\"U\\\\\\\"\\\\\\\\t\\\\\\\\\\\\\"hello\\\\\\\\\\\\\"\\\\\\\\n\\\\\\\"\",type=\"const char32_t \[10\]\",thread-id=\"1\",has_more=\"0\"")
|
||||
|
||||
# Test that -gdb-set print char-array-as-string fails if "on"/"off" isn't specified
|
||||
self.runCmd("-gdb-set print char-array-as-string")
|
||||
|
|
|
@ -57,12 +57,12 @@ var_list_children_test(void)
|
|||
void
|
||||
gdb_set_show_print_char_array_as_string_test(void)
|
||||
{
|
||||
const char *cp = "hello";
|
||||
const char ca[] = "hello";
|
||||
const char16_t *u16p = u"hello";
|
||||
const char16_t u16a[] = u"hello";
|
||||
const char32_t *u32p = U"hello";
|
||||
const char32_t u32a[] = U"hello";
|
||||
const char *cp = "\t\"hello\"\n";
|
||||
const char ca[] = "\t\"hello\"\n";
|
||||
const char16_t *u16p = u"\t\"hello\"\n";
|
||||
const char16_t u16a[] = u"\t\"hello\"\n";
|
||||
const char32_t *u32p = U"\t\"hello\"\n";
|
||||
const char32_t u32a[] = U"\t\"hello\"\n";
|
||||
|
||||
// BP_gdb_set_show_print_char_array_as_string_test
|
||||
}
|
||||
|
|
|
@ -285,7 +285,7 @@ CMICmnLLDBDebugSessionInfoVarObj::GetValueStringFormatted(const lldb::SBValue &v
|
|||
}
|
||||
}
|
||||
|
||||
return utilValue.GetValue().Escape().AddSlashes();
|
||||
return utilValue.GetValue().AddSlashes();
|
||||
}
|
||||
|
||||
//++ ------------------------------------------------------------------------------------
|
||||
|
|
|
@ -237,8 +237,7 @@ CMICmnLLDBUtilSBValue::GetSimpleValueCStringPointer(void) const
|
|||
case lldb::eBasicTypeSignedChar:
|
||||
case lldb::eBasicTypeUnsignedChar:
|
||||
{
|
||||
// FIXME Add slashes before double quotes
|
||||
const CMIUtilString prefix(ReadCStringFromHostMemory<char>(child).AddSlashes());
|
||||
const CMIUtilString prefix(ReadCStringFromHostMemory<char>(child));
|
||||
// Note code that has const in will not show the text suffix to the string pointer
|
||||
// i.e. const char * pMyStr = "blah"; ==> "0x00007000"" <-- Eclipse shows this
|
||||
// but char * pMyStr = "blah"; ==> "0x00007000" "blah"" <-- Eclipse shows this
|
||||
|
@ -246,14 +245,12 @@ CMICmnLLDBUtilSBValue::GetSimpleValueCStringPointer(void) const
|
|||
}
|
||||
case lldb::eBasicTypeChar16:
|
||||
{
|
||||
// FIXME Add slashes before double quotes
|
||||
const CMIUtilString prefix(ReadCStringFromHostMemory<char16_t>(child).AddSlashes());
|
||||
const CMIUtilString prefix(ReadCStringFromHostMemory<char16_t>(child));
|
||||
return CMIUtilString::Format("%s u\"%s\"", value, prefix.c_str());
|
||||
}
|
||||
case lldb::eBasicTypeChar32:
|
||||
{
|
||||
// FIXME Add slashes before double quotes
|
||||
const CMIUtilString prefix(ReadCStringFromHostMemory<char32_t>(child).AddSlashes());
|
||||
const CMIUtilString prefix(ReadCStringFromHostMemory<char32_t>(child));
|
||||
return CMIUtilString::Format("%s U\"%s\"", value, prefix.c_str());
|
||||
}
|
||||
}
|
||||
|
@ -280,22 +277,19 @@ CMICmnLLDBUtilSBValue::GetSimpleValueCStringArray(void) const
|
|||
case lldb::eBasicTypeSignedChar:
|
||||
case lldb::eBasicTypeUnsignedChar:
|
||||
{
|
||||
// FIXME Add slashes before double quotes
|
||||
const CMIUtilString prefix(ReadCStringFromHostMemory<char>(m_rValue, nChildren).AddSlashes());
|
||||
const CMIUtilString prefix(ReadCStringFromHostMemory<char>(m_rValue, nChildren));
|
||||
// TODO: to match char* it should be the following
|
||||
// return CMIUtilString::Format("[%u] \"%s\"", nChildren, prefix.c_str());
|
||||
return CMIUtilString::Format("\"%s\"", prefix.c_str());
|
||||
}
|
||||
case lldb::eBasicTypeChar16:
|
||||
{
|
||||
// FIXME Add slashes before double quotes
|
||||
const CMIUtilString prefix(ReadCStringFromHostMemory<char16_t>(m_rValue, nChildren).AddSlashes());
|
||||
const CMIUtilString prefix(ReadCStringFromHostMemory<char16_t>(m_rValue, nChildren));
|
||||
return CMIUtilString::Format("u\"%s\"", prefix.c_str());
|
||||
}
|
||||
case lldb::eBasicTypeChar32:
|
||||
{
|
||||
// FIXME Add slashes before double quotes
|
||||
const CMIUtilString prefix(ReadCStringFromHostMemory<char32_t>(m_rValue, nChildren).AddSlashes());
|
||||
const CMIUtilString prefix(ReadCStringFromHostMemory<char32_t>(m_rValue, nChildren));
|
||||
return CMIUtilString::Format("U\"%s\"", prefix.c_str());
|
||||
}
|
||||
}
|
||||
|
@ -472,7 +466,7 @@ CMICmnLLDBUtilSBValue::ReadCStringFromHostMemory(lldb::SBValue &vrValue, const M
|
|||
return m_pUnkwn;
|
||||
else if (ch == 0)
|
||||
break;
|
||||
result.append(CMIUtilString::ConvertToPrintableASCII(ch));
|
||||
result.append(CMIUtilString::ConvertToPrintableASCII(ch, true /* bEscapeQuotes */));
|
||||
addr += sizeof(ch);
|
||||
}
|
||||
|
||||
|
|
|
@ -895,7 +895,7 @@ CMIUtilString::StripSlashes(void) const
|
|||
}
|
||||
|
||||
CMIUtilString
|
||||
CMIUtilString::ConvertToPrintableASCII(const char vChar)
|
||||
CMIUtilString::ConvertToPrintableASCII(const char vChar, bool bEscapeQuotes)
|
||||
{
|
||||
switch (vChar)
|
||||
{
|
||||
|
@ -917,6 +917,10 @@ CMIUtilString::ConvertToPrintableASCII(const char vChar)
|
|||
return "\\e";
|
||||
case '\\':
|
||||
return "\\\\";
|
||||
case '"':
|
||||
if (bEscapeQuotes)
|
||||
return "\\\"";
|
||||
// fall thru
|
||||
default:
|
||||
if (::isprint(vChar))
|
||||
return Format("%c", vChar);
|
||||
|
@ -926,24 +930,65 @@ CMIUtilString::ConvertToPrintableASCII(const char vChar)
|
|||
}
|
||||
|
||||
CMIUtilString
|
||||
CMIUtilString::ConvertToPrintableASCII(const char16_t vChar16)
|
||||
CMIUtilString::ConvertCharValueToPrintableASCII(char vChar, bool bEscapeQuotes)
|
||||
{
|
||||
if (vChar16 == (char16_t)(char)vChar16 && ::isprint(vChar16))
|
||||
switch (vChar)
|
||||
{
|
||||
case '\a':
|
||||
return "\\a";
|
||||
case '\b':
|
||||
return "\\b";
|
||||
case '\t':
|
||||
return "\\t";
|
||||
case '\n':
|
||||
return "\\n";
|
||||
case '\v':
|
||||
return "\\v";
|
||||
case '\f':
|
||||
return "\\f";
|
||||
case '\r':
|
||||
return "\\r";
|
||||
case '\033':
|
||||
return "\\e";
|
||||
case '\\':
|
||||
return "\\\\";
|
||||
case '"':
|
||||
if (bEscapeQuotes)
|
||||
return "\\\"";
|
||||
// fall thru
|
||||
default:
|
||||
if (::isprint(vChar))
|
||||
return Format("%c", vChar);
|
||||
else
|
||||
return CMIUtilString();
|
||||
}
|
||||
}
|
||||
|
||||
CMIUtilString
|
||||
CMIUtilString::ConvertToPrintableASCII(const char16_t vChar16, bool bEscapeQuotes)
|
||||
{
|
||||
if (vChar16 == (char16_t)(char)vChar16)
|
||||
{
|
||||
// Convert char16_t to char (if possible)
|
||||
return Format("%c", vChar16);
|
||||
else
|
||||
return Format("\\u%02" PRIx8 "%02" PRIx8,
|
||||
CMIUtilString str = ConvertCharValueToPrintableASCII((char)vChar16, bEscapeQuotes);
|
||||
if (str.length() > 0)
|
||||
return str;
|
||||
}
|
||||
return Format("\\u%02" PRIx8 "%02" PRIx8,
|
||||
(vChar16 >> 8) & 0xff, vChar16 & 0xff);
|
||||
}
|
||||
|
||||
CMIUtilString
|
||||
CMIUtilString::ConvertToPrintableASCII(const char32_t vChar32)
|
||||
CMIUtilString::ConvertToPrintableASCII(const char32_t vChar32, bool bEscapeQuotes)
|
||||
{
|
||||
if (vChar32 == (char32_t)(char)vChar32 && ::isprint(vChar32))
|
||||
if (vChar32 == (char32_t)(char)vChar32)
|
||||
{
|
||||
// Convert char32_t to char (if possible)
|
||||
return Format("%c", vChar32);
|
||||
else
|
||||
return Format("\\U%02" PRIx8 "%02" PRIx8 "%02" PRIx8 "%02" PRIx8,
|
||||
CMIUtilString str = ConvertCharValueToPrintableASCII((char)vChar32, bEscapeQuotes);
|
||||
if (str.length() > 0)
|
||||
return str;
|
||||
}
|
||||
return Format("\\U%02" PRIx8 "%02" PRIx8 "%02" PRIx8 "%02" PRIx8,
|
||||
(vChar32 >> 24) & 0xff, (vChar32 >> 16) & 0xff,
|
||||
(vChar32 >> 8) & 0xff, vChar32 & 0xff);
|
||||
}
|
||||
|
|
|
@ -34,9 +34,9 @@ class CMIUtilString : public std::string
|
|||
static CMIUtilString FormatValist(const CMIUtilString &vrFormating, va_list vArgs);
|
||||
static bool IsAllValidAlphaAndNumeric(const char *vpText);
|
||||
static bool Compare(const CMIUtilString &vrLhs, const CMIUtilString &vrRhs);
|
||||
static CMIUtilString ConvertToPrintableASCII(const char vChar);
|
||||
static CMIUtilString ConvertToPrintableASCII(const char16_t vChar16);
|
||||
static CMIUtilString ConvertToPrintableASCII(const char32_t vChar32);
|
||||
static CMIUtilString ConvertToPrintableASCII(const char vChar, bool bEscapeQuotes = false);
|
||||
static CMIUtilString ConvertToPrintableASCII(const char16_t vChar16, bool bEscapeQuotes = false);
|
||||
static CMIUtilString ConvertToPrintableASCII(const char32_t vChar32, bool bEscapeQuotes = false);
|
||||
|
||||
// Methods:
|
||||
public:
|
||||
|
@ -75,6 +75,7 @@ class CMIUtilString : public std::string
|
|||
// Static method:
|
||||
private:
|
||||
static CMIUtilString FormatPriv(const CMIUtilString &vrFormat, va_list vArgs);
|
||||
static CMIUtilString ConvertCharValueToPrintableASCII(char vChar, bool bEscapeQuotes);
|
||||
|
||||
// Methods:
|
||||
private:
|
||||
|
|
Loading…
Reference in New Issue