forked from OSchip/llvm-project
Add support for Unicode strings in CMICmnLLDBUtilSBValue::GetValue (MI)
This patch includes the following changes: # Add CMIUtilString::ConvertToASCII to convert unicode to ASCII (MI) # Rework CMICmnLLDBUtilSBValue::GetSimpleValue to print wide/unicode char (MI) ## Add CMICmnLLDBUtilSBValue::GetSimpleValueChar ## Extend CMICmnLLDBUtilSBValue::IsCharType to accept char16_t/char32_t ## Don't ignore the fail_value in SBValue::GetValueAsUnsigned # Rework CMIUtilString::ConvertToASCII (MI) ## Don't use templates ## Change the function signature to convert signle characters (was std::basic_string) ## Rename CMIUtilString::ConvertToASCII to CMIUtilString::ConvertToPrintableASCII # Add CMIUtilString::ConvertToPrintableASCII for char (MI) ## Refactor CMIUtilString::Escape ## Simplify CMICmnLLDBUtilSBValue::GetSimpleValueChar for char # Add char16_t* and char32_t* support in CMICmnLLDBUtilSBValue::GetSimpleValue (MI) ## Add CMICmnLLDBUtilSBValue::GetSimpleValueCStringPointer ## Add CMICmnLLDBUtilSBValue::ReadCStringFromHostMemory2 (it's extended version of CMICmnLLDBUtilSBValue::ReadCStringFromHostMemory) # Improve error checking in CMICmnLLDBUtilSBValue::GetSimpleValueChar (MI) # Refactor CMICmnLLDBUtilSBValue (MI) ## Remove CMICmnLLDBUtilSBValue::ReadCStringFromHostMemory (use CMICmnLLDBUtilSBValue::ReadCStringFromHostMemory2 instead) ## Rename CMICmnLLDBUtilSBValue::ReadCStringFromHostMemory2 to CMICmnLLDBUtilSBValue::ReadCStringFromHostMemory ## Move CMICmnLLDBUtilSBValue::GetValueCString to private methods ## Rename CMICmnLLDBUtilSBValue::GetValueCString to CMICmnLLDBUtilSBValue::GetSimpleValueCStringArray ## Remove CMICmnLLDBUtilSBValue::GetChildValueCString # Improve MiGdbSetShowTestCase.test_lldbmi_gdb_set_show_print_char_array_as_string test to check char16_t/char32_t (MI) # Fix CMICmnLLDBUtilSBValue::GetSimpleValueCStringArray for Unicode (MI) ## Fix handling of char16_t and char32_t ## Improve CMICmnLLDBUtilSBValue::ReadCStringFromHostMemory to read variables of type char[]: add vnMaxLen argument ## Turn on few cases to check char16_t[] and char32_t[] output in MiGdbSetShowTestCase.test_lldbmi_gdb_set_show_print_char_array_as_string # Remove unnecessary checks in CMICmnLLDBUtilSBValue (MI) llvm-svn: 236827
This commit is contained in:
parent
84dc009bef
commit
b9bfd969e3
|
@ -36,12 +36,28 @@ class MiGdbSetShowTestCase(lldbmi_testcase.MiTestCaseBase):
|
|||
self.expect("\^done,value=\"off\"")
|
||||
|
||||
# Test that an char* is expanded to string when print char-array-as-string is "off"
|
||||
self.runCmd("-var-create var1 * string_ptr")
|
||||
self.expect("\^done,name=\"var1\",numchild=\"1\",value=\"0x[0-9a-f]+ \\\\\\\"string - const char \*\\\\\\\"\",type=\"const char \*\",thread-id=\"1\",has_more=\"0\"")
|
||||
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 "off"
|
||||
self.runCmd("-var-create var2 * string_arr")
|
||||
self.expect("\^done,name=\"var2\",numchild=\"17\",value=\"\[17\]\",type=\"const char \[17\]\",thread-id=\"1\",has_more=\"0\"")
|
||||
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\"")
|
||||
|
||||
# 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\"")
|
||||
|
||||
# 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\"")
|
||||
|
||||
# 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\"")
|
||||
|
||||
# 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\"")
|
||||
|
||||
# Test that -gdb-set can set print char-array-as-string flag
|
||||
self.runCmd("-gdb-set print char-array-as-string on")
|
||||
|
@ -52,12 +68,28 @@ class MiGdbSetShowTestCase(lldbmi_testcase.MiTestCaseBase):
|
|||
self.expect("\^done,value=\"on\"")
|
||||
|
||||
# Test that an char* is expanded to string when print char-array-as-string is "on"
|
||||
self.runCmd("-var-create var1 * string_ptr")
|
||||
self.expect("\^done,name=\"var1\",numchild=\"1\",value=\"0x[0-9a-f]+ \\\\\\\"string - const char \*\\\\\\\"\",type=\"const char \*\",thread-id=\"1\",has_more=\"0\"")
|
||||
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.runCmd("-var-create var2 * string_arr")
|
||||
self.expect("\^done,name=\"var2\",numchild=\"17\",value=\"\\\\\\\"string - char \[\]\\\\\\\"\",type=\"const char \[17\]\",thread-id=\"1\",has_more=\"0\"")
|
||||
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.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.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.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.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\"")
|
||||
|
||||
# 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")
|
||||
|
|
|
@ -47,8 +47,12 @@ var_list_children(void)
|
|||
void
|
||||
gdb_set_show_print_char_array_as_string_test(void)
|
||||
{
|
||||
const char *string_ptr = "string - const char *";
|
||||
const char string_arr[] = "string - char []";
|
||||
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";
|
||||
|
||||
// BP_gdb_set_show_print_char_array_as_string_test
|
||||
}
|
||||
|
|
|
@ -7,6 +7,9 @@
|
|||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// Third party headers:
|
||||
#include <cinttypes>
|
||||
|
||||
// In-house headers:
|
||||
#include "MICmnLLDBUtilSBValue.h"
|
||||
#include "MICmnLLDBDebugSessionInfo.h"
|
||||
|
@ -121,14 +124,12 @@ CMICmnLLDBUtilSBValue::GetSimpleValue(const bool vbHandleArrayType, CMIUtilStrin
|
|||
{
|
||||
if (m_bHandleCharType && IsCharType())
|
||||
{
|
||||
const uint8_t value = m_rValue.GetValueAsUnsigned();
|
||||
const CMIUtilString prefix(CMIUtilString::Format("%c", value).Escape().AddSlashes());
|
||||
vwrValue = CMIUtilString::Format("%hhu '%s'", value, prefix.c_str());
|
||||
vwrValue = GetSimpleValueChar();
|
||||
return MIstatus::success;
|
||||
}
|
||||
else
|
||||
{
|
||||
const MIchar *pValue = m_bValidSBValue ? m_rValue.GetValue() : nullptr;
|
||||
const MIchar *pValue = m_rValue.GetValue();
|
||||
vwrValue = pValue != nullptr ? pValue : m_pUnkwn;
|
||||
return MIstatus::success;
|
||||
}
|
||||
|
@ -137,18 +138,12 @@ CMICmnLLDBUtilSBValue::GetSimpleValue(const bool vbHandleArrayType, CMIUtilStrin
|
|||
{
|
||||
if (m_bHandleCharType && IsFirstChildCharType())
|
||||
{
|
||||
const MIchar *pValue = m_bValidSBValue ? m_rValue.GetValue() : nullptr;
|
||||
const CMIUtilString value = pValue != nullptr ? pValue : m_pUnkwn;
|
||||
const CMIUtilString prefix(GetChildValueCString().Escape().AddSlashes());
|
||||
// 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
|
||||
vwrValue = CMIUtilString::Format("%s \"%s\"", value.c_str(), prefix.c_str());
|
||||
vwrValue = GetSimpleValueCStringPointer();
|
||||
return MIstatus::success;
|
||||
}
|
||||
else
|
||||
{
|
||||
const MIchar *pValue = m_bValidSBValue ? m_rValue.GetValue() : nullptr;
|
||||
const MIchar *pValue = m_rValue.GetValue();
|
||||
vwrValue = pValue != nullptr ? pValue : m_pUnkwn;
|
||||
return MIstatus::success;
|
||||
}
|
||||
|
@ -161,10 +156,7 @@ CMICmnLLDBUtilSBValue::GetSimpleValue(const bool vbHandleArrayType, CMIUtilStrin
|
|||
bPrintCharArrayAsString) && bPrintCharArrayAsString;
|
||||
if (bPrintCharArrayAsString && m_bHandleCharType && IsFirstChildCharType())
|
||||
{
|
||||
// TODO: to match char* it should be the following
|
||||
// vwrValue = CMIUtilString::Format("[%u] \"%s\"", nChildren, prefix.c_str());
|
||||
const CMIUtilString prefix(GetValueCString().Escape().AddSlashes());
|
||||
vwrValue = CMIUtilString::Format("\"%s\"", prefix.c_str());
|
||||
vwrValue = GetSimpleValueCStringArray();
|
||||
return MIstatus::success;
|
||||
}
|
||||
else if (vbHandleArrayType)
|
||||
|
@ -178,6 +170,137 @@ CMICmnLLDBUtilSBValue::GetSimpleValue(const bool vbHandleArrayType, CMIUtilStrin
|
|||
return MIstatus::failure;
|
||||
}
|
||||
|
||||
//++ ------------------------------------------------------------------------------------
|
||||
// Details: Retrieve from the LLDB SB Value object the char value of the variable.
|
||||
// Type: Method.
|
||||
// Args: None.
|
||||
// Return: CMIUtilString - The char value of the variable.
|
||||
// Throws: None.
|
||||
//--
|
||||
CMIUtilString
|
||||
CMICmnLLDBUtilSBValue::GetSimpleValueChar(void) const
|
||||
{
|
||||
const uint64_t value = m_rValue.GetValueAsUnsigned();
|
||||
if (value == 0)
|
||||
{
|
||||
const uint64_t nFailValue = 1;
|
||||
if (nFailValue == m_rValue.GetValueAsUnsigned(nFailValue))
|
||||
return m_pUnkwn;
|
||||
}
|
||||
|
||||
const lldb::BasicType eType = m_rValue.GetType().GetBasicType();
|
||||
switch (eType)
|
||||
{
|
||||
default:
|
||||
assert(0 && "value must be a char type");
|
||||
case lldb::eBasicTypeChar:
|
||||
case lldb::eBasicTypeSignedChar:
|
||||
case lldb::eBasicTypeUnsignedChar:
|
||||
{
|
||||
const CMIUtilString prefix(CMIUtilString::ConvertToPrintableASCII((char)value));
|
||||
return CMIUtilString::Format("%" PRIu8 " '%s'", (uint8_t)value, prefix.c_str());
|
||||
}
|
||||
case lldb::eBasicTypeChar16:
|
||||
{
|
||||
const CMIUtilString prefix(CMIUtilString::ConvertToPrintableASCII((char16_t)value));
|
||||
return CMIUtilString::Format("U+%04" PRIx16 " u'%s'", (uint16_t)value, prefix.c_str());
|
||||
}
|
||||
case lldb::eBasicTypeChar32:
|
||||
{
|
||||
const CMIUtilString prefix(CMIUtilString::ConvertToPrintableASCII((char32_t)value));
|
||||
return CMIUtilString::Format("U+%08" PRIx32 " U'%s'", (uint32_t)value, prefix.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//++ ------------------------------------------------------------------------------------
|
||||
// Details: Retrieve from the LLDB SB Value object of type char* the c-string value.
|
||||
// Type: Method.
|
||||
// Args: None.
|
||||
// Return: CMIUtilString - The c-string value of the variable.
|
||||
// Throws: None.
|
||||
//--
|
||||
CMIUtilString
|
||||
CMICmnLLDBUtilSBValue::GetSimpleValueCStringPointer(void) const
|
||||
{
|
||||
const MIchar *value = m_rValue.GetValue();
|
||||
if (value == nullptr)
|
||||
return m_pUnkwn;
|
||||
|
||||
lldb::SBValue child = m_rValue.GetChildAtIndex(0);
|
||||
const lldb::BasicType eType = child.GetType().GetBasicType();
|
||||
switch (eType)
|
||||
{
|
||||
default:
|
||||
assert(0 && "child must be a char type");
|
||||
case lldb::eBasicTypeChar:
|
||||
case lldb::eBasicTypeSignedChar:
|
||||
case lldb::eBasicTypeUnsignedChar:
|
||||
{
|
||||
// FIXME Add slashes before double quotes
|
||||
const CMIUtilString prefix(ReadCStringFromHostMemory<char>(child).AddSlashes());
|
||||
// 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
|
||||
return CMIUtilString::Format("%s \"%s\"", value, prefix.c_str());
|
||||
}
|
||||
case lldb::eBasicTypeChar16:
|
||||
{
|
||||
// FIXME Add slashes before double quotes
|
||||
const CMIUtilString prefix(ReadCStringFromHostMemory<char16_t>(child).AddSlashes());
|
||||
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());
|
||||
return CMIUtilString::Format("%s U\"%s\"", value, prefix.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//++ ------------------------------------------------------------------------------------
|
||||
// Details: Retrieve from the LLDB SB Value object of type char[] the c-string value.
|
||||
// Type: Method.
|
||||
// Args: None.
|
||||
// Return: CMIUtilString - The c-string value of the variable.
|
||||
// Throws: None.
|
||||
//--
|
||||
CMIUtilString
|
||||
CMICmnLLDBUtilSBValue::GetSimpleValueCStringArray(void) const
|
||||
{
|
||||
const MIuint nChildren = m_rValue.GetNumChildren();
|
||||
lldb::SBValue child = m_rValue.GetChildAtIndex(0);
|
||||
const lldb::BasicType eType = child.GetType().GetBasicType();
|
||||
switch (eType)
|
||||
{
|
||||
default:
|
||||
assert(0 && "value must be a char[] type");
|
||||
case lldb::eBasicTypeChar:
|
||||
case lldb::eBasicTypeSignedChar:
|
||||
case lldb::eBasicTypeUnsignedChar:
|
||||
{
|
||||
// FIXME Add slashes before double quotes
|
||||
const CMIUtilString prefix(ReadCStringFromHostMemory<char>(m_rValue, nChildren).AddSlashes());
|
||||
// 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());
|
||||
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());
|
||||
return CMIUtilString::Format("U\"%s\"", prefix.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
CMICmnLLDBUtilSBValue::GetCompositeValue(const bool vbPrintFieldNames, CMICmnMIValueTuple &vwrMiValueTuple,
|
||||
const MIuint vnDepth /* = 1 */) const
|
||||
|
@ -234,28 +357,6 @@ CMICmnLLDBUtilSBValue::GetCompositeValue(const bool vbPrintFieldNames, CMICmnMIV
|
|||
return MIstatus::success;
|
||||
}
|
||||
|
||||
//++ ------------------------------------------------------------------------------------
|
||||
// Details: If the LLDB SB Value object is a char or char[] type then form the text data
|
||||
// string otherwise return nothing. m_bHandleCharType must be true to return
|
||||
// text data if any.
|
||||
// Type: Method.
|
||||
// Args: None.
|
||||
// Return: CMIUtilString - Text description of the variable's value.
|
||||
// Throws: None.
|
||||
//--
|
||||
CMIUtilString
|
||||
CMICmnLLDBUtilSBValue::GetValueCString(void) const
|
||||
{
|
||||
CMIUtilString text;
|
||||
|
||||
if (m_bHandleCharType && (IsCharType() || (IsArrayType() && IsFirstChildCharType())))
|
||||
{
|
||||
text = ReadCStringFromHostMemory(m_rValue);
|
||||
}
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
//++ ------------------------------------------------------------------------------------
|
||||
// Details: Retrieve the flag stating whether this value object is a char type or some
|
||||
// other type. Char type can be signed or unsigned.
|
||||
|
@ -268,7 +369,17 @@ bool
|
|||
CMICmnLLDBUtilSBValue::IsCharType(void) const
|
||||
{
|
||||
const lldb::BasicType eType = m_rValue.GetType().GetBasicType();
|
||||
return ((eType == lldb::eBasicTypeChar) || (eType == lldb::eBasicTypeSignedChar) || (eType == lldb::eBasicTypeUnsignedChar));
|
||||
switch (eType)
|
||||
{
|
||||
case lldb::eBasicTypeChar:
|
||||
case lldb::eBasicTypeSignedChar:
|
||||
case lldb::eBasicTypeUnsignedChar:
|
||||
case lldb::eBasicTypeChar16:
|
||||
case lldb::eBasicTypeChar32:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//++ ------------------------------------------------------------------------------------
|
||||
|
@ -341,62 +452,35 @@ CMICmnLLDBUtilSBValue::IsArrayType(void) const
|
|||
return m_rValue.GetType().IsArrayType();
|
||||
}
|
||||
|
||||
//++ ------------------------------------------------------------------------------------
|
||||
// Details: Retrieve the C string data for a child of char type (one and only child) for
|
||||
// the parent value object. If the child is not a char type or the parent has
|
||||
// more than one child then an empty string is returned. Char type can be
|
||||
// signed or unsigned.
|
||||
// Type: Method.
|
||||
// Args: None.
|
||||
// Return: CMIUtilString - Text description of the variable's value.
|
||||
// Throws: None.
|
||||
//--
|
||||
CMIUtilString
|
||||
CMICmnLLDBUtilSBValue::GetChildValueCString(void) const
|
||||
{
|
||||
CMIUtilString text;
|
||||
const MIuint nChildren = m_rValue.GetNumChildren();
|
||||
|
||||
// Is it a basic type
|
||||
if (nChildren == 0)
|
||||
return text;
|
||||
|
||||
// Is it a composite type
|
||||
if (nChildren > 1)
|
||||
return text;
|
||||
|
||||
lldb::SBValue member = m_rValue.GetChildAtIndex(0);
|
||||
const CMICmnLLDBUtilSBValue utilValue(member);
|
||||
if (m_bHandleCharType && utilValue.IsCharType())
|
||||
{
|
||||
text = ReadCStringFromHostMemory(member);
|
||||
}
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
//++ ------------------------------------------------------------------------------------
|
||||
// Details: Retrieve the C string data of value object by read the memory where the
|
||||
// variable is held.
|
||||
// Type: Method.
|
||||
// Args: vrValueObj - (R) LLDB SBValue variable object.
|
||||
// Args: vrValue - (R) LLDB SBValue variable object.
|
||||
// Return: CMIUtilString - Text description of the variable's value.
|
||||
// Throws: None.
|
||||
//--
|
||||
template <typename charT>
|
||||
CMIUtilString
|
||||
CMICmnLLDBUtilSBValue::ReadCStringFromHostMemory(const lldb::SBValue &vrValueObj) const
|
||||
CMICmnLLDBUtilSBValue::ReadCStringFromHostMemory(lldb::SBValue &vrValue, const MIuint vnMaxLen) const
|
||||
{
|
||||
CMIUtilString text;
|
||||
|
||||
lldb::SBValue &rValue = const_cast<lldb::SBValue &>(vrValueObj);
|
||||
const lldb::addr_t addr = rValue.GetLoadAddress();
|
||||
CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
|
||||
const MIuint nBytes(128);
|
||||
std::unique_ptr<char[]> apBufferMemory(new char[nBytes]);
|
||||
std::string result;
|
||||
lldb::addr_t addr = vrValue.GetLoadAddress(), end_addr = addr + vnMaxLen * sizeof(charT);
|
||||
lldb::SBProcess process = CMICmnLLDBDebugSessionInfo::Instance().GetProcess();
|
||||
lldb::SBError error;
|
||||
const MIuint64 nReadBytes = rSessionInfo.GetProcess().ReadMemory(addr, apBufferMemory.get(), nBytes, error);
|
||||
MIunused(nReadBytes);
|
||||
return CMIUtilString(apBufferMemory.get());
|
||||
while (addr < end_addr)
|
||||
{
|
||||
charT ch;
|
||||
const MIuint64 nReadBytes = process.ReadMemory(addr, &ch, sizeof(ch), error);
|
||||
if (error.Fail() || nReadBytes != sizeof(ch))
|
||||
return m_pUnkwn;
|
||||
else if (ch == 0)
|
||||
break;
|
||||
result.append(CMIUtilString::ConvertToPrintableASCII(ch));
|
||||
addr += sizeof(ch);
|
||||
}
|
||||
|
||||
return result.c_str();
|
||||
}
|
||||
|
||||
//++ ------------------------------------------------------------------------------------
|
||||
|
|
|
@ -36,8 +36,6 @@ class CMICmnLLDBUtilSBValue
|
|||
//
|
||||
CMIUtilString GetName(void) const;
|
||||
CMIUtilString GetValue(const bool vbExpandAggregates = false) const;
|
||||
CMIUtilString GetValueCString(void) const;
|
||||
CMIUtilString GetChildValueCString(void) const;
|
||||
CMIUtilString GetTypeName(void) const;
|
||||
CMIUtilString GetTypeNameDisplay(void) const;
|
||||
bool IsCharType(void) const;
|
||||
|
@ -53,8 +51,11 @@ class CMICmnLLDBUtilSBValue
|
|||
|
||||
// Methods:
|
||||
private:
|
||||
CMIUtilString ReadCStringFromHostMemory(const lldb::SBValue &vrValueObj) const;
|
||||
template <typename charT> CMIUtilString ReadCStringFromHostMemory(lldb::SBValue &vrValue, const MIuint vnMaxLen = UINT32_MAX) const;
|
||||
bool GetSimpleValue(const bool vbHandleArrayType, CMIUtilString &vrValue) const;
|
||||
CMIUtilString GetSimpleValueChar(void) const;
|
||||
CMIUtilString GetSimpleValueCStringPointer(void) const;
|
||||
CMIUtilString GetSimpleValueCStringArray(void) const;
|
||||
bool GetCompositeValue(const bool vbPrintFieldNames, CMICmnMIValueTuple &vwrMiValueTuple, const MIuint vnDepth = 1) const;
|
||||
|
||||
// Attributes:
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
|
||||
// In-house headers:
|
||||
#include "MIUtilString.h"
|
||||
#include "Platform.h"
|
||||
|
||||
//++ ------------------------------------------------------------------------------------
|
||||
// Details: CMIUtilString constructor.
|
||||
|
@ -804,54 +803,10 @@ CMIUtilString::Escape(const bool vbEscapeQuotes /* = false */) const
|
|||
for (MIuint nIndex(0); nIndex < nLen; ++nIndex)
|
||||
{
|
||||
const MIchar cUnescapedChar((*this)[nIndex]);
|
||||
switch (cUnescapedChar)
|
||||
{
|
||||
case '\a':
|
||||
strNew.append("\\a");
|
||||
break;
|
||||
case '\b':
|
||||
strNew.append("\\b");
|
||||
break;
|
||||
case '\t':
|
||||
strNew.append("\\t");
|
||||
break;
|
||||
case '\n':
|
||||
strNew.append("\\n");
|
||||
break;
|
||||
case '\v':
|
||||
strNew.append("\\v");
|
||||
break;
|
||||
case '\f':
|
||||
strNew.append("\\f");
|
||||
break;
|
||||
case '\r':
|
||||
strNew.append("\\r");
|
||||
break;
|
||||
case '\033':
|
||||
strNew.append("\\e");
|
||||
break;
|
||||
case '\\':
|
||||
strNew.append("\\\\");
|
||||
break;
|
||||
case '\"':
|
||||
if (vbEscapeQuotes)
|
||||
{
|
||||
strNew.append("\\\"");
|
||||
break;
|
||||
}
|
||||
// FALLTHROUGH
|
||||
default:
|
||||
if (::isprint(cUnescapedChar))
|
||||
strNew.push_back(cUnescapedChar);
|
||||
else
|
||||
{
|
||||
const size_t size = sizeof("\\xXX");
|
||||
char strEscapedChar[size];
|
||||
::snprintf(strEscapedChar, size, "\\x%02" PRIx8, cUnescapedChar);
|
||||
strNew.append(strEscapedChar);
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (cUnescapedChar == '"' && vbEscapeQuotes)
|
||||
strNew.append("\\\"");
|
||||
else
|
||||
strNew.append(ConvertToPrintableASCII((char)cUnescapedChar));
|
||||
}
|
||||
return strNew;
|
||||
}
|
||||
|
@ -939,3 +894,57 @@ CMIUtilString::StripSlashes(void) const
|
|||
|
||||
return strNew;
|
||||
}
|
||||
|
||||
CMIUtilString
|
||||
CMIUtilString::ConvertToPrintableASCII(const char vChar)
|
||||
{
|
||||
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 "\\\\";
|
||||
default:
|
||||
if (::isprint(vChar))
|
||||
return Format("%c", vChar);
|
||||
else
|
||||
return Format("\\x%02" PRIx8, vChar);
|
||||
}
|
||||
}
|
||||
|
||||
CMIUtilString
|
||||
CMIUtilString::ConvertToPrintableASCII(const char16_t vChar16)
|
||||
{
|
||||
if (vChar16 == (char16_t)(char)vChar16 && ::isprint(vChar16))
|
||||
// Convert char16_t to char (if possible)
|
||||
return Format("%c", vChar16);
|
||||
else
|
||||
return Format("\\u%02" PRIx8 "%02" PRIx8,
|
||||
(vChar16 >> 8) & 0xff, vChar16 & 0xff);
|
||||
}
|
||||
|
||||
CMIUtilString
|
||||
CMIUtilString::ConvertToPrintableASCII(const char32_t vChar32)
|
||||
{
|
||||
if (vChar32 == (char32_t)(char)vChar32 && ::isprint(vChar32))
|
||||
// Convert char32_t to char (if possible)
|
||||
return Format("%c", vChar32);
|
||||
else
|
||||
return Format("\\U%02" PRIx8 "%02" PRIx8 "%02" PRIx8 "%02" PRIx8,
|
||||
(vChar32 >> 24) & 0xff, (vChar32 >> 16) & 0xff,
|
||||
(vChar32 >> 8) & 0xff, vChar32 & 0xff);
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
// Third party headers:
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <cinttypes>
|
||||
|
||||
// In-house headers:
|
||||
#include "MIDataTypes.h"
|
||||
|
@ -36,6 +37,9 @@ class CMIUtilString : public std::string
|
|||
static CMIUtilString FormatValist(const CMIUtilString &vrFormating, va_list vArgs);
|
||||
static bool IsAllValidAlphaAndNumeric(const MIchar &vrText);
|
||||
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);
|
||||
|
||||
// Methods:
|
||||
public:
|
||||
|
|
Loading…
Reference in New Issue