Index: tools/lldb-mi/MICmnLLDBDebuggerHandleEvents.h =================================================================== --- tools/lldb-mi/MICmnLLDBDebuggerHandleEvents.h +++ tools/lldb-mi/MICmnLLDBDebuggerHandleEvents.h @@ -86,7 +86,6 @@ bool TextToStdout(const CMIUtilString &vrTxt); bool TextToStderr(const CMIUtilString &vrTxt); bool UpdateSelectedThread(void); - bool ConvertPrintfCtrlCodeToString(const MIchar vCtrl, CMIUtilString &vwrStrEquivalent); // Overridden: private: Index: tools/lldb-mi/MICmnLLDBDebuggerHandleEvents.cpp =================================================================== --- tools/lldb-mi/MICmnLLDBDebuggerHandleEvents.cpp +++ tools/lldb-mi/MICmnLLDBDebuggerHandleEvents.cpp @@ -1379,26 +1379,24 @@ bool CMICmnLLDBDebuggerHandleEvents::GetProcessStdout(void) { - bool bOk = MIstatus::success; - - char c; - size_t nBytes = 0; CMIUtilString text; + std::shared_ptr spStdoutBuffer(new char[1024]); lldb::SBProcess process = CMICmnLLDBDebugSessionInfo::Instance().GetDebugger().GetSelectedTarget().GetProcess(); - while (process.GetSTDOUT(&c, 1) > 0) + while (1) { - CMIUtilString str; - if (ConvertPrintfCtrlCodeToString(c, str)) - text += str; - nBytes++; - } - if (nBytes > 0) - { - const CMIUtilString t(CMIUtilString::Format("~\"%s\"", text.c_str())); - bOk = TextToStdout(t); + const size_t nBytes = process.GetSTDOUT(spStdoutBuffer.get(), 1024); + if (nBytes == 0) + break; + + text.append(spStdoutBuffer.get(), nBytes); } - return bOk; + if (text.empty()) + return MIstatus::success; + + const bool bEscapeQuotes(true); + const CMIUtilString t(CMIUtilString::Format("~\"%s\"", text.Escape(bEscapeQuotes).c_str())); + return TextToStdout(t); } //++ ------------------------------------------------------------------------------------ @@ -1414,72 +1412,24 @@ bool CMICmnLLDBDebuggerHandleEvents::GetProcessStderr(void) { - bool bOk = MIstatus::success; - - char c; - size_t nBytes = 0; CMIUtilString text; + std::shared_ptr spStderrBuffer(new char[1024]); lldb::SBProcess process = CMICmnLLDBDebugSessionInfo::Instance().GetDebugger().GetSelectedTarget().GetProcess(); - while (process.GetSTDERR(&c, 1) > 0) - { - CMIUtilString str; - if (ConvertPrintfCtrlCodeToString(c, str)) - text += str; - nBytes++; - } - if (nBytes > 0) - { - const CMIUtilString t(CMIUtilString::Format("~\"%s\"", text.c_str())); - bOk = TextToStdout(t); - } - - return bOk; -} - -//++ ------------------------------------------------------------------------------------ -// Details: Convert text stream control codes to text equivalent. -// Type: Method. -// Args: vCtrl - (R) The control code. -// vwrStrEquivalent - (W) The text equivalent. -// Return: MIstatus::success - Functionality succeeded. -// MIstatus::failure - Functionality failed. -// Throws: None. -//-- -bool -CMICmnLLDBDebuggerHandleEvents::ConvertPrintfCtrlCodeToString(const MIchar vCtrl, CMIUtilString &vwrStrEquivalent) -{ - switch (vCtrl) + while (1) { - case '\033': - vwrStrEquivalent = "\\e"; - break; - case '\a': - vwrStrEquivalent = "\\a"; - break; - case '\b': - vwrStrEquivalent = "\\b"; - break; - case '\f': - vwrStrEquivalent = "\\f"; - break; - case '\n': - vwrStrEquivalent = "\\n"; - break; - case '\r': - vwrStrEquivalent = "\\r"; - break; - case '\t': - vwrStrEquivalent = "\\t"; - break; - case '\v': - vwrStrEquivalent = "\\v"; - break; - default: - vwrStrEquivalent = CMIUtilString::Format("%c", vCtrl); + const size_t nBytes = process.GetSTDERR(spStderrBuffer.get(), 1024); + if (nBytes == 0) break; + + text.append(spStderrBuffer.get(), nBytes); } - return MIstatus::success; + if (text.empty()) + return MIstatus::success; + + const bool bEscapeQuotes(true); + const CMIUtilString t(CMIUtilString::Format("~\"%s\"", text.Escape(bEscapeQuotes).c_str())); + return TextToStdout(t); } //++ ------------------------------------------------------------------------------------ Index: tools/lldb-mi/MIUtilString.h =================================================================== --- tools/lldb-mi/MIUtilString.h +++ tools/lldb-mi/MIUtilString.h @@ -72,6 +72,7 @@ MIuint FindFirst(const CMIUtilString &vrPattern, const bool vbSkipQuotedText, bool &vrwbNotFoundClosedQuote, const MIuint vnPos = 0) const; MIuint FindFirstNot(const CMIUtilString &vrPattern, const MIuint vnPos = 0) const; + CMIUtilString Escape(const bool vbEscapeQuotes = false) const; // CMIUtilString &operator=(const MIchar *vpRhs); CMIUtilString &operator=(const std::string &vrRhs); Index: tools/lldb-mi/MIUtilString.cpp =================================================================== --- tools/lldb-mi/MIUtilString.cpp +++ tools/lldb-mi/MIUtilString.cpp @@ -797,3 +797,70 @@ return (MIuint)std::string::npos; } + +//++ ------------------------------------------------------------------------------------ +// Details: Get escaped string from *this string. +// Type: Method. +// Args: None. +// Return: CMIUtilString - The escaped version of the initial string. +// Throws: None. +//-- +CMIUtilString +CMIUtilString::Escape(const bool vbEscapeQuotes /* = false */) const +{ + const MIuint nLen(length()); + CMIUtilString strNew; + strNew.reserve(nLen); + 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 + { + char strEscapedChar[sizeof("\\xXX")]; + ::sprintf(strEscapedChar, "\\x%02hhx", cUnescapedChar); + strNew.append(strEscapedChar); + } + break; + } + } + return strNew; +}