Index: test/tools/lldb-mi/variable/TestMiGdbSetShowPrint.py =================================================================== --- test/tools/lldb-mi/variable/TestMiGdbSetShowPrint.py +++ test/tools/lldb-mi/variable/TestMiGdbSetShowPrint.py @@ -37,27 +37,27 @@ # 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,30 @@ 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") Index: test/tools/lldb-mi/variable/main.cpp =================================================================== --- test/tools/lldb-mi/variable/main.cpp +++ test/tools/lldb-mi/variable/main.cpp @@ -57,12 +57,12 @@ 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 } Index: tools/lldb-mi/MICmnLLDBDebugSessionInfoVarObj.cpp =================================================================== --- tools/lldb-mi/MICmnLLDBDebugSessionInfoVarObj.cpp +++ tools/lldb-mi/MICmnLLDBDebugSessionInfoVarObj.cpp @@ -285,7 +285,7 @@ } } - return utilValue.GetValue().Escape().AddSlashes(); + return utilValue.GetValue().AddSlashes(); } //++ ------------------------------------------------------------------------------------ Index: tools/lldb-mi/MICmnLLDBUtilSBValue.cpp =================================================================== --- tools/lldb-mi/MICmnLLDBUtilSBValue.cpp +++ tools/lldb-mi/MICmnLLDBUtilSBValue.cpp @@ -237,8 +237,7 @@ case lldb::eBasicTypeSignedChar: case lldb::eBasicTypeUnsignedChar: { - // FIXME Add slashes before double quotes - const CMIUtilString prefix(ReadCStringFromHostMemory(child).AddSlashes()); + const CMIUtilString prefix(ReadCStringFromHostMemory(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 @@ } case lldb::eBasicTypeChar16: { - // FIXME Add slashes before double quotes - const CMIUtilString prefix(ReadCStringFromHostMemory(child).AddSlashes()); + const CMIUtilString prefix(ReadCStringFromHostMemory(child)); return CMIUtilString::Format("%s u\"%s\"", value, prefix.c_str()); } case lldb::eBasicTypeChar32: { - // FIXME Add slashes before double quotes - const CMIUtilString prefix(ReadCStringFromHostMemory(child).AddSlashes()); + const CMIUtilString prefix(ReadCStringFromHostMemory(child)); return CMIUtilString::Format("%s U\"%s\"", value, prefix.c_str()); } } @@ -280,22 +277,19 @@ case lldb::eBasicTypeSignedChar: case lldb::eBasicTypeUnsignedChar: { - // FIXME Add slashes before double quotes - const CMIUtilString prefix(ReadCStringFromHostMemory(m_rValue, nChildren).AddSlashes()); + const CMIUtilString prefix(ReadCStringFromHostMemory(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(m_rValue, nChildren).AddSlashes()); + const CMIUtilString prefix(ReadCStringFromHostMemory(m_rValue, nChildren)); return CMIUtilString::Format("u\"%s\"", prefix.c_str()); } case lldb::eBasicTypeChar32: { - // FIXME Add slashes before double quotes - const CMIUtilString prefix(ReadCStringFromHostMemory(m_rValue, nChildren).AddSlashes()); + const CMIUtilString prefix(ReadCStringFromHostMemory(m_rValue, nChildren)); return CMIUtilString::Format("U\"%s\"", prefix.c_str()); } } @@ -476,7 +470,7 @@ return m_pUnkwn; else if (ch == 0) break; - result.append(CMIUtilString::ConvertToPrintableASCII(ch)); + result.append(CMIUtilString::ConvertToPrintableASCII(ch, true /* bEscapeQuotes */)); addr += sizeof(ch); } Index: tools/lldb-mi/MIUtilString.h =================================================================== --- tools/lldb-mi/MIUtilString.h +++ tools/lldb-mi/MIUtilString.h @@ -37,9 +37,9 @@ 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); + 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: @@ -78,6 +78,7 @@ // Static method: private: static CMIUtilString FormatPriv(const CMIUtilString &vrFormat, va_list vArgs); + static CMIUtilString ConvertCharValueToPrintableASCII(char vChar, bool bEscapeQuotes); // Methods: private: Index: tools/lldb-mi/MIUtilString.cpp =================================================================== --- tools/lldb-mi/MIUtilString.cpp +++ tools/lldb-mi/MIUtilString.cpp @@ -896,7 +896,7 @@ } CMIUtilString -CMIUtilString::ConvertToPrintableASCII(const char vChar) +CMIUtilString::ConvertToPrintableASCII(const char vChar, bool bEscapeQuotes) { switch (vChar) { @@ -918,6 +918,10 @@ return "\\e"; case '\\': return "\\\\"; + case '"': + if (bEscapeQuotes) + return "\\\""; + // fall thru default: if (::isprint(vChar)) return Format("%c", vChar); @@ -927,24 +931,65 @@ } 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); }