[Lldb-commits] [lldb] r247899 - [lldb-mi] Fix the handling of files in -data-info-line and -symbol-list-lines.
Sean Callanan via lldb-commits
lldb-commits at lists.llvm.org
Thu Sep 17 10:43:53 PDT 2015
Dawn,
this breaks the OS X Xcode build because it can’t find “../lib/Support/regex_impl.h”.
I only see that header in llvm/lib, but so far lldb-mi hasn’t had any LLVM dependencies and it doesn’t even have the right header search paths in Xcode. Should we be adding the LLVM headers as search paths?
Sean
> On Sep 17, 2015, at 9:22 AM, Dawn Perchik via lldb-commits <lldb-commits at lists.llvm.org> wrote:
>
> Author: dperchik
> Date: Thu Sep 17 11:22:30 2015
> New Revision: 247899
>
> URL: http://llvm.org/viewvc/llvm-project?rev=247899&view=rev
> Log:
> [lldb-mi] Fix the handling of files in -data-info-line and -symbol-list-lines.
>
> This fixes -data-info-line and -symbol-list-lines to parse the filename
> and line correctly when line entries don't have the optional column
> number and the filename contains a Windows drive letter. It also fixes
> -symbol-list-lines when code from header files is generated.
>
> Reviewed by: abidh, ki.stfu
> Subscribers: lldb-commits
> Differential Revision: http://reviews.llvm.org/D12115
>
> Added:
> lldb/trunk/test/tools/lldb-mi/symbol/symbol_list_lines_inline_test.cpp
> lldb/trunk/test/tools/lldb-mi/symbol/symbol_list_lines_inline_test.h
> lldb/trunk/test/tools/lldb-mi/symbol/symbol_list_lines_inline_test2.cpp
> lldb/trunk/tools/lldb-mi/MIUtilParse.cpp
> lldb/trunk/tools/lldb-mi/MIUtilParse.h
> Modified:
> lldb/trunk/test/tools/lldb-mi/symbol/Makefile
> lldb/trunk/test/tools/lldb-mi/symbol/TestMiSymbol.py
> lldb/trunk/test/tools/lldb-mi/symbol/main.cpp
> lldb/trunk/tools/lldb-mi/CMakeLists.txt
> lldb/trunk/tools/lldb-mi/MICmdCmdData.cpp
> lldb/trunk/tools/lldb-mi/MICmdCmdSymbol.cpp
> lldb/trunk/tools/lldb-mi/MIUtilString.cpp
> lldb/trunk/tools/lldb-mi/MIUtilString.h
>
> Modified: lldb/trunk/test/tools/lldb-mi/symbol/Makefile
> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/tools/lldb-mi/symbol/Makefile?rev=247899&r1=247898&r2=247899&view=diff
> ==============================================================================
> --- lldb/trunk/test/tools/lldb-mi/symbol/Makefile (original)
> +++ lldb/trunk/test/tools/lldb-mi/symbol/Makefile Thu Sep 17 11:22:30 2015
> @@ -1,5 +1,5 @@
> LEVEL = ../../../make
>
> -CXX_SOURCES := main.cpp
> +CXX_SOURCES := main.cpp symbol_list_lines_inline_test.cpp symbol_list_lines_inline_test2.cpp
>
> include $(LEVEL)/Makefile.rules
>
> Modified: lldb/trunk/test/tools/lldb-mi/symbol/TestMiSymbol.py
> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/tools/lldb-mi/symbol/TestMiSymbol.py?rev=247899&r1=247898&r2=247899&view=diff
> ==============================================================================
> --- lldb/trunk/test/tools/lldb-mi/symbol/TestMiSymbol.py (original)
> +++ lldb/trunk/test/tools/lldb-mi/symbol/TestMiSymbol.py Thu Sep 17 11:22:30 2015
> @@ -39,6 +39,19 @@ class MiSymbolTestCase(lldbmi_testcase.M
> self.runCmd("-symbol-list-lines main.cpp")
> self.expect("\^done,lines=\[\{pc=\"0x0*%x\",line=\"%d\"\}(,\{pc=\"0x[0-9a-f]+\",line=\"\d+\"\})+\]" % (addr, line))
>
> + # Test that -symbol-list-lines doesn't include lines from other sources
> + # by checking the first and last line, and making sure the other lines
> + # are between 30 and 39.
> + sline = line_number('symbol_list_lines_inline_test2.cpp', '// FUNC_gfunc2')
> + eline = line_number('symbol_list_lines_inline_test2.cpp', '// END_gfunc2')
> + self.runCmd("-symbol-list-lines symbol_list_lines_inline_test2.cpp")
> + self.expect("\^done,lines=\[\{pc=\"0x[0-9a-f]+\",line=\"%d\"\}(,\{pc=\"0x[0-9a-f]+\",line=\"3\d\"\})*,\{pc=\"0x[0-9a-f]+\",line=\"%d\"\}\]" % (sline, eline))
> + ##FIXME: This doesn't work for symbol_list_lines_inline_test.cpp due to clang bug llvm.org/pr24716
> + ##sline = line_number('symbol_list_lines_inline_test.cpp', '// FUNC_gfunc')
> + ##eline = line_number('symbol_list_lines_inline_test.cpp', '// STRUCT_s')
> + ##self.runCmd("-symbol-list-lines symbol_list_lines_inline_test.cpp")
> + ##self.expect("\^done,lines=\[\{pc=\"0x[0-9a-f]+\",line=\"%d\"\}(,\{pc=\"0x[0-9a-f]+\",line=\"3\d\"\})*,\{pc=\"0x[0-9a-f]+\",line=\"%d\"\}\]" % (sline, eline))
> +
> # Test that -symbol-list-lines fails when file doesn't exist
> self.runCmd("-symbol-list-lines unknown_file")
> self.expect("\^error,message=\"warning: No source filenames matched 'unknown_file'\. error: no source filenames matched any command arguments \"")
>
> Modified: lldb/trunk/test/tools/lldb-mi/symbol/main.cpp
> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/tools/lldb-mi/symbol/main.cpp?rev=247899&r1=247898&r2=247899&view=diff
> ==============================================================================
> --- lldb/trunk/test/tools/lldb-mi/symbol/main.cpp (original)
> +++ lldb/trunk/test/tools/lldb-mi/symbol/main.cpp Thu Sep 17 11:22:30 2015
> @@ -7,8 +7,12 @@
> //
> //===----------------------------------------------------------------------===//
>
> +extern int j;
> +extern int gfunc(int i);
> +extern int gfunc2(int i);
> int
> -main(int argc, char const *argv[])
> +main()
> { // FUNC_main
> - return 0;
> + int i = gfunc(j) + gfunc2(j);
> + return i == 0;
> }
>
> Added: lldb/trunk/test/tools/lldb-mi/symbol/symbol_list_lines_inline_test.cpp
> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/tools/lldb-mi/symbol/symbol_list_lines_inline_test.cpp?rev=247899&view=auto
> ==============================================================================
> --- lldb/trunk/test/tools/lldb-mi/symbol/symbol_list_lines_inline_test.cpp (added)
> +++ lldb/trunk/test/tools/lldb-mi/symbol/symbol_list_lines_inline_test.cpp Thu Sep 17 11:22:30 2015
> @@ -0,0 +1,39 @@
> +// Skip lines so we can make sure we're not seeing any lines from
> +// symbol_list_lines_inline_test.h included in -symbol-list-lines
> +// symbol_list_lines_inline_test.cpp, by checking that all the lines
> +// are between 30 and 39.
> +// line 5
> +// line 6
> +// line 7
> +// line 8
> +// line 9
> +// line 10
> +// line 11
> +// line 12
> +// line 13
> +// line 14
> +// line 15
> +// line 16
> +// line 17
> +// line 18
> +// line 19
> +// line 20
> +// line 21
> +// line 22
> +// line 23
> +// line 24
> +// line 25
> +// line 26
> +// line 27
> +// line 28
> +// line 29
> +#include "symbol_list_lines_inline_test.h"
> +int
> +gfunc(int i)
> +{ // FUNC_gfunc
> + return ns::ifunc(i);
> +}
> +namespace ns
> +{
> +S s; // STRUCT_s
> +}
>
> Added: lldb/trunk/test/tools/lldb-mi/symbol/symbol_list_lines_inline_test.h
> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/tools/lldb-mi/symbol/symbol_list_lines_inline_test.h?rev=247899&view=auto
> ==============================================================================
> --- lldb/trunk/test/tools/lldb-mi/symbol/symbol_list_lines_inline_test.h (added)
> +++ lldb/trunk/test/tools/lldb-mi/symbol/symbol_list_lines_inline_test.h Thu Sep 17 11:22:30 2015
> @@ -0,0 +1,24 @@
> +namespace ns
> +{
> +inline int
> +ifunc(int i)
> +{
> + return i;
> +}
> +struct S
> +{
> + int a;
> + int b;
> + S()
> + : a(3)
> + , b(4)
> + {
> + }
> + int
> + mfunc()
> + {
> + return a + b;
> + }
> +};
> +extern S s;
> +}
>
> Added: lldb/trunk/test/tools/lldb-mi/symbol/symbol_list_lines_inline_test2.cpp
> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/tools/lldb-mi/symbol/symbol_list_lines_inline_test2.cpp?rev=247899&view=auto
> ==============================================================================
> --- lldb/trunk/test/tools/lldb-mi/symbol/symbol_list_lines_inline_test2.cpp (added)
> +++ lldb/trunk/test/tools/lldb-mi/symbol/symbol_list_lines_inline_test2.cpp Thu Sep 17 11:22:30 2015
> @@ -0,0 +1,38 @@
> +// Skip lines so we can make sure we're not seeing any lines from
> +// symbol_list_lines_inline_test.h included in -symbol-list-lines
> +// symbol_list_lines_inline_test2.cpp, by checking that all the lines
> +// are between 30 and 39.
> +// line 5
> +// line 6
> +// line 7
> +// line 8
> +// line 9
> +// line 10
> +// line 11
> +// line 12
> +// line 13
> +// line 14
> +// line 15
> +// line 16
> +// line 17
> +// line 18
> +// line 19
> +// line 20
> +// line 21
> +// line 22
> +// line 23
> +// line 24
> +// line 25
> +// line 26
> +// line 27
> +// line 28
> +// line 29
> +#include "symbol_list_lines_inline_test.h"
> +int j = 2;
> +int
> +gfunc2(int i)
> +{ // FUNC_gfunc2
> + i += ns::s.mfunc();
> + i += ns::ifunc(i);
> + return i == 0; // END_gfunc2
> +}
>
> Modified: lldb/trunk/tools/lldb-mi/CMakeLists.txt
> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/lldb-mi/CMakeLists.txt?rev=247899&r1=247898&r2=247899&view=diff
> ==============================================================================
> --- lldb/trunk/tools/lldb-mi/CMakeLists.txt (original)
> +++ lldb/trunk/tools/lldb-mi/CMakeLists.txt Thu Sep 17 11:22:30 2015
> @@ -65,6 +65,7 @@ set(LLDB_MI_SOURCES
> MIDriverBase.cpp
> MIDriverMain.cpp
> MIDriverMgr.cpp
> + MIUtilParse.cpp
> MIUtilDateTimeStd.cpp
> MIUtilDebug.cpp
> MIUtilFileStd.cpp
>
> Modified: lldb/trunk/tools/lldb-mi/MICmdCmdData.cpp
> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/lldb-mi/MICmdCmdData.cpp?rev=247899&r1=247898&r2=247899&view=diff
> ==============================================================================
> --- lldb/trunk/tools/lldb-mi/MICmdCmdData.cpp (original)
> +++ lldb/trunk/tools/lldb-mi/MICmdCmdData.cpp Thu Sep 17 11:22:30 2015
> @@ -42,6 +42,7 @@
> #include "MICmdArgValConsume.h"
> #include "MICmnLLDBDebugSessionInfoVarObj.h"
> #include "MICmnLLDBUtilSBValue.h"
> +#include "MIUtilParse.h"
>
> //++ ------------------------------------------------------------------------------------
> // Details: CMICmdCmdDataEvaluateExpression constructor.
> @@ -1642,6 +1643,53 @@ CMICmdCmdDataInfoLine::Execute()
> }
>
> //++ ------------------------------------------------------------------------------------
> +// Details: Helper function for parsing a line entry returned from lldb for the command:
> +// target modules lookup -v <location>
> +// where the line entry is of the format:
> +// LineEntry: \[0x0000000100000f37-0x0000000100000f45\): /path/file:3[:1]
> +// start end file line column(opt)
> +// Args: input - (R) Input string to parse.
> +// start - (W) String representing the start address.
> +// end - (W) String representing the end address.
> +// file - (W) String representing the file.
> +// line - (W) String representing the line.
> +// Return: bool - True = input was parsed successfully, false = input could not be parsed.
> +// Throws: None.
> +//--
> +static bool
> +ParseLLDBLineEntry(const char *input, CMIUtilString &start, CMIUtilString &end,
> + CMIUtilString &file, CMIUtilString &line)
> +{
> + // Note: Ambiguities arise because the column is optional, and
> + // because : can appear in filenames or as a byte in a multibyte
> + // UTF8 character. We keep those cases to a minimum by using regex
> + // to work on the string from both the left and right, so that what
> + // is remains is assumed to be the filename.
> +
> + // Match LineEntry using regex.
> + static MIUtilParse::CRegexParser g_lineentry_nocol_regex(
> + "^ *LineEntry: \\[(0x[0-9a-fA-F]+)-(0x[0-9a-fA-F]+)\\): (.+):([0-9]+)$");
> + static MIUtilParse::CRegexParser g_lineentry_col_regex(
> + "^ *LineEntry: \\[(0x[0-9a-fA-F]+)-(0x[0-9a-fA-F]+)\\): (.+):([0-9]+):[0-9]+$");
> + // ^1=start ^2=end ^3=f ^4=line ^5=:col(opt)
> +
> + MIUtilParse::CRegexParser::Match match(6);
> +
> + // First try matching the LineEntry with the column,
> + // then try without the column.
> + const bool ok = g_lineentry_col_regex.Execute(input, match) ||
> + g_lineentry_nocol_regex.Execute(input, match);
> + if (ok)
> + {
> + start = match.GetMatchAtIndex(1);
> + end = match.GetMatchAtIndex(2);
> + file = match.GetMatchAtIndex(3);
> + line = match.GetMatchAtIndex(4);
> + }
> + return ok;
> +}
> +
> +//++ ------------------------------------------------------------------------------------
> // Details: The invoker requires this function. The command prepares a MI Record Result
> // for the work carried out in the Execute().
> // Type: Overridden.
> @@ -1672,58 +1720,25 @@ CMICmdCmdDataInfoLine::Acknowledge()
> // String looks like:
> // LineEntry: \[0x0000000100000f37-0x0000000100000f45\): /path/to/file:3[:1]
> const CMIUtilString &rLine(vecLines[i]);
> + CMIUtilString strStart;
> + CMIUtilString strEnd;
> + CMIUtilString strFile;
> + CMIUtilString strLine;
>
> - // LineEntry: \[0x0000000100000f37-0x0000000100000f45\): /path/to/file:3[:1]
> - // ^^^^^^^^^ -- property
> - const size_t nPropertyStartPos = rLine.find_first_not_of(' ');
> - const size_t nPropertyEndPos = rLine.find(':');
> - const size_t nPropertyLen = nPropertyEndPos - nPropertyStartPos;
> - const CMIUtilString strProperty(rLine.substr(nPropertyStartPos, nPropertyLen).c_str());
> -
> - // Skip all except LineEntry
> - if (!CMIUtilString::Compare(strProperty, "LineEntry"))
> + if (!ParseLLDBLineEntry(rLine.c_str(), strStart, strEnd, strFile, strLine))
> continue;
>
> - // LineEntry: \[0x0000000100000f37-0x0000000100000f45\): /path/to/file:3[:1]
> - // ^^^^^^^^^^^^^^^^^^ -- start address
> - const size_t nStartAddressStartPos = rLine.find('[');
> - const size_t nStartAddressEndPos = rLine.find('-');
> - const size_t nStartAddressLen = nStartAddressEndPos - nStartAddressStartPos - 1;
> - const CMIUtilString strStartAddress(rLine.substr(nStartAddressStartPos + 1, nStartAddressLen).c_str());
> - const CMICmnMIValueConst miValueConst(strStartAddress);
> + const CMICmnMIValueConst miValueConst(strStart);
> const CMICmnMIValueResult miValueResult("start", miValueConst);
> - CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult);
> -
> - // LineEntry: \[0x0000000100000f37-0x0000000100000f45\): /path/to/file:3[:1]
> - // ^^^^^^^^^^^^^^^^^^ -- end address
> - const size_t nEndAddressEndPos = rLine.find(')');
> - const size_t nEndAddressLen = nEndAddressEndPos - nStartAddressEndPos - 1;
> - const CMIUtilString strEndAddress(rLine.substr(nStartAddressEndPos + 1, nEndAddressLen).c_str());
> - const CMICmnMIValueConst miValueConst2(strEndAddress);
> + CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken,
> + CMICmnMIResultRecord::eResultClass_Done,
> + miValueResult);
> + const CMICmnMIValueConst miValueConst2(strEnd);
> const CMICmnMIValueResult miValueResult2("end", miValueConst2);
> miRecordResult.Add(miValueResult2);
> -
> - // LineEntry: \[0x0000000100000f37-0x0000000100000f45\): /path/to/file:3[:1]
> - // ^^^^^^^^^^^^^ -- file
> - // ^ -- line
> - // ^ -- column (optional)
> - const size_t nFileStartPos = rLine.find_first_not_of(' ', nEndAddressEndPos + 2);
> - const size_t nFileOrLineEndPos = rLine.rfind(':');
> - const size_t nFileOrLineStartPos = rLine.rfind(':', nFileOrLineEndPos - 1);
> - const size_t nFileEndPos = nFileStartPos < nFileOrLineStartPos ? nFileOrLineStartPos : nFileOrLineEndPos;
> - const size_t nFileLen = nFileEndPos - nFileStartPos;
> - const CMIUtilString strFile(rLine.substr(nFileStartPos, nFileLen).c_str());
> const CMICmnMIValueConst miValueConst3(strFile);
> const CMICmnMIValueResult miValueResult3("file", miValueConst3);
> miRecordResult.Add(miValueResult3);
> -
> - // LineEntry: \[0x0000000100000f37-0x0000000100000f45\): /path/to/file:3[:1]
> - // ^ -- line
> - const size_t nLineStartPos = nFileEndPos + 1;
> - const size_t nLineEndPos = rLine.find(':', nLineStartPos);
> - const size_t nLineLen = nLineEndPos != std::string::npos ? nLineEndPos - nLineStartPos
> - : std::string::npos;
> - const CMIUtilString strLine(rLine.substr(nLineStartPos, nLineLen).c_str());
> const CMICmnMIValueConst miValueConst4(strLine);
> const CMICmnMIValueResult miValueResult4("line", miValueConst4);
> miRecordResult.Add(miValueResult4);
>
> Modified: lldb/trunk/tools/lldb-mi/MICmdCmdSymbol.cpp
> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/lldb-mi/MICmdCmdSymbol.cpp?rev=247899&r1=247898&r2=247899&view=diff
> ==============================================================================
> --- lldb/trunk/tools/lldb-mi/MICmdCmdSymbol.cpp (original)
> +++ lldb/trunk/tools/lldb-mi/MICmdCmdSymbol.cpp Thu Sep 17 11:22:30 2015
> @@ -19,6 +19,7 @@
> #include "MICmnMIResultRecord.h"
> #include "MICmnMIValueList.h"
> #include "MICmnMIValueTuple.h"
> +#include "MIUtilParse.h"
>
> //++ ------------------------------------------------------------------------------------
> // Details: CMICmdCmdSymbolListLines constructor.
> @@ -81,6 +82,10 @@ CMICmdCmdSymbolListLines::Execute()
> CMICMDBASE_GETOPTION(pArgFile, File, m_constStrArgNameFile);
>
> const CMIUtilString &strFilePath(pArgFile->GetValue());
> + // FIXME: this won't work for header files! To try and use existing
> + // commands to get this to work for header files would be too slow.
> + // Instead, this code should be rewritten to use APIs and/or support
> + // should be added to lldb which would work for header files.
> const CMIUtilString strCmd(CMIUtilString::Format("target modules dump line-table \"%s\"", strFilePath.AddSlashes().c_str()));
>
> CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
> @@ -91,6 +96,77 @@ CMICmdCmdSymbolListLines::Execute()
> }
>
> //++ ------------------------------------------------------------------------------------
> +// Details: Helper function for parsing the header returned from lldb for the command:
> +// target modules dump line-table <file>
> +// where the header is of the format:
> +// Line table for /path/to/file in `/path/to/module
> +// Args: input - (R) Input string to parse.
> +// file - (W) String representing the file.
> +// Return: bool - True = input was parsed successfully, false = input could not be parsed.
> +// Throws: None.
> +//--
> +static bool
> +ParseLLDBLineAddressHeader(const char *input, CMIUtilString &file)
> +{
> + // Match LineEntry using regex.
> + static MIUtilParse::CRegexParser g_lineentry_header_regex(
> + "^ *Line table for (.+) in `(.+)$");
> + // ^1=file ^2=module
> +
> + MIUtilParse::CRegexParser::Match match(3);
> +
> + const bool ok = g_lineentry_header_regex.Execute(input, match);
> + if (ok)
> + file = match.GetMatchAtIndex(1);
> + return ok;
> +}
> +
> +//++ ------------------------------------------------------------------------------------
> +// Details: Helper function for parsing a line entry returned from lldb for the command:
> +// target modules dump line-table <file>
> +// where the line entry is of the format:
> +// 0x0000000100000e70: /path/to/file:3002[:4]
> +// addr file line column(opt)
> +// Args: input - (R) Input string to parse.
> +// addr - (W) String representing the pc address.
> +// file - (W) String representing the file.
> +// line - (W) String representing the line.
> +// Return: bool - True = input was parsed successfully, false = input could not be parsed.
> +// Throws: None.
> +//--
> +static bool
> +ParseLLDBLineAddressEntry(const char *input, CMIUtilString &addr,
> + CMIUtilString &file, CMIUtilString &line)
> +{
> + // Note: Ambiguities arise because the column is optional, and
> + // because : can appear in filenames or as a byte in a multibyte
> + // UTF8 character. We keep those cases to a minimum by using regex
> + // to work on the string from both the left and right, so that what
> + // is remains is assumed to be the filename.
> +
> + // Match LineEntry using regex.
> + static MIUtilParse::CRegexParser g_lineentry_nocol_regex(
> + "^ *(0x[0-9a-fA-F]+): (.+):([0-9]+)$");
> + static MIUtilParse::CRegexParser g_lineentry_col_regex(
> + "^ *(0x[0-9a-fA-F]+): (.+):([0-9]+):[0-9]+$");
> + // ^1=addr ^2=f ^3=line ^4=:col(opt)
> +
> + MIUtilParse::CRegexParser::Match match(5);
> +
> + // First try matching the LineEntry with the column,
> + // then try without the column.
> + const bool ok = g_lineentry_col_regex.Execute(input, match) ||
> + g_lineentry_nocol_regex.Execute(input, match);
> + if (ok)
> + {
> + addr = match.GetMatchAtIndex(1);
> + file = match.GetMatchAtIndex(2);
> + line = match.GetMatchAtIndex(3);
> + }
> + return ok;
> +}
> +
> +//++ ------------------------------------------------------------------------------------
> // Details: The invoker requires this function. The command prepares a MI Record Result
> // for the work carried out in the Execute().
> // Type: Overridden.
> @@ -117,29 +193,43 @@ CMICmdCmdSymbolListLines::Acknowledge()
> const CMIUtilString strLldbMsg(m_lldbResult.GetOutput());
> const MIuint nLines(strLldbMsg.SplitLines(vecLines));
>
> + // Parse the file from the header.
> + const CMIUtilString &rWantFile(vecLines[0]);
> + CMIUtilString strWantFile;
> + if (!ParseLLDBLineAddressHeader(rWantFile.c_str(), strWantFile))
> + {
> + // Unexpected error - parsing failed.
> + // MI print "%s^error,msg=\"Command '-symbol-list-lines'. Error: Line address header is absent or has an unknown format.\""
> + const CMICmnMIValueConst miValueConst(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_SOME_ERROR), m_cmdData.strMiCmd.c_str(), "Line address header is absent or has an unknown format."));
> + const CMICmnMIValueResult miValueResult("msg", miValueConst);
> + const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult);
> + m_miResultRecord = miRecordResult;
> +
> + return MIstatus::success;
> + }
> +
> + // Parse the line address entries.
> CMICmnMIValueList miValueList(true);
> for (MIuint i = 1; i < nLines; ++i)
> {
> // String looks like:
> // 0x0000000100000e70: /path/to/file:3[:4]
> const CMIUtilString &rLine(vecLines[i]);
> + CMIUtilString strAddr;
> + CMIUtilString strFile;
> + CMIUtilString strLine;
> +
> + if (!ParseLLDBLineAddressEntry(rLine.c_str(), strAddr, strFile, strLine))
> + continue;
> +
> + // Skip entries which don't match the desired source.
> + if (strWantFile != strFile)
> + continue;
>
> - // 0x0000000100000e70: /path/to/file:3[:4]
> - // ^^^^^^^^^^^^^^^^^^ -- pc
> - const size_t nAddrEndPos = rLine.find(':');
> - const CMIUtilString strAddr(rLine.substr(0, nAddrEndPos).c_str());
> const CMICmnMIValueConst miValueConst(strAddr);
> const CMICmnMIValueResult miValueResult("pc", miValueConst);
> CMICmnMIValueTuple miValueTuple(miValueResult);
>
> - // 0x0000000100000e70: /path/to/file:3[:4]
> - // ^ -- line
> - const size_t nLineOrColumnStartPos = rLine.rfind(':');
> - const CMIUtilString strLineOrColumn(rLine.substr(nLineOrColumnStartPos + 1).c_str());
> - const size_t nPathOrLineStartPos = rLine.rfind(':', nLineOrColumnStartPos - 1);
> - const size_t nPathOrLineLen = nLineOrColumnStartPos - nPathOrLineStartPos - 1;
> - const CMIUtilString strPathOrLine(rLine.substr(nPathOrLineStartPos + 1, nPathOrLineLen).c_str());
> - const CMIUtilString strLine(strPathOrLine.IsNumber() ? strPathOrLine : strLineOrColumn);
> const CMICmnMIValueConst miValueConst2(strLine);
> const CMICmnMIValueResult miValueResult2("line", miValueConst2);
> miValueTuple.Add(miValueResult2);
>
> Added: lldb/trunk/tools/lldb-mi/MIUtilParse.cpp
> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/lldb-mi/MIUtilParse.cpp?rev=247899&view=auto
> ==============================================================================
> --- lldb/trunk/tools/lldb-mi/MIUtilParse.cpp (added)
> +++ lldb/trunk/tools/lldb-mi/MIUtilParse.cpp Thu Sep 17 11:22:30 2015
> @@ -0,0 +1,75 @@
> +//===-- MIUtilParse.cpp ----------------------------------------*- C++ -*-===//
> +//
> +// The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
> +//===----------------------------------------------------------------------===//
> +
> +// Third party headers:
> +#include <memory>
> +
> +// In-house headers:
> +#include "MIUtilParse.h"
> +
> +//++ ------------------------------------------------------------------------------------
> +// Details: CRegexParser constructor.
> +// Type: Method.
> +// Args: regexStr - Pointer to the regular expression to compile.
> +// Return: None.
> +// Throws: None.
> +//--
> +MIUtilParse::CRegexParser::CRegexParser(const char *regexStr)
> + : m_isValid(llvm_regcomp(&m_emma, regexStr, REG_EXTENDED) == 0)
> +{
> +}
> +
> +//++ ------------------------------------------------------------------------------------
> +// Details: CRegexParser destructor.
> +// Type: Method.
> +// Args: None.
> +// Return: None.
> +// Throws: None.
> +//--
> +MIUtilParse::CRegexParser::~CRegexParser()
> +{
> + // Free up memory held within regex.
> + if (m_isValid)
> + llvm_regfree(&m_emma);
> +}
> +
> +//++ ------------------------------------------------------------------------------------
> +// Details: CRegexParser regex executer.
> +// Match the input against the regular expression. Return an error
> +// if the number of matches is less than minMatches. If the default
> +// minMatches value of 0 is passed, an error will be returned if
> +// the number of matches is less than the maxMatches value used to
> +// initialize Match.
> +// Type: Method.
> +// Args: input (R) - Pointer to UTF8 text data to be parsed.
> +// match (RW) - Reference to Match class.
> +// minMatches (R) - Minimum number of regex matches expected.
> +// Return: bool - True = minimum matches were met,
> +// false = minimum matches were not met or regex failed.
> +// Throws: None.
> +//--
> +bool
> +MIUtilParse::CRegexParser::Execute(const char *input, Match& match, size_t minMatches)
> +{
> + if (!m_isValid)
> + return false;
> +
> + std::unique_ptr<llvm_regmatch_t[]> matches(new llvm_regmatch_t[match.m_maxMatches]); // Array of matches
> +
> + if (llvm_regexec(&m_emma, input, match.m_maxMatches, matches.get(), 0) != 0)
> + return false;
> +
> + size_t i;
> + for (i = 0; i < match.m_maxMatches && matches[i].rm_so >= 0; i++)
> + {
> + const int n = matches[i].rm_eo - matches[i].rm_so;
> + match.m_matchStrs[i].assign(input + matches[i].rm_so, n);
> + }
> + return i >= minMatches;
> +}
>
> Added: lldb/trunk/tools/lldb-mi/MIUtilParse.h
> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/lldb-mi/MIUtilParse.h?rev=247899&view=auto
> ==============================================================================
> --- lldb/trunk/tools/lldb-mi/MIUtilParse.h (added)
> +++ lldb/trunk/tools/lldb-mi/MIUtilParse.h Thu Sep 17 11:22:30 2015
> @@ -0,0 +1,93 @@
> +//===-- MIUtilParse.h ------------------------------------------*- C++ -*-===//
> +//
> +// The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
> +//===----------------------------------------------------------------------===//
> +
> +#pragma once
> +
> +// Third party headers:
> +#include "../lib/Support/regex_impl.h"
> +
> +// In-house headers:
> +#include "MIUtilString.h"
> +
> +namespace MIUtilParse
> +{
> +
> +//++ ============================================================================
> +// Details: MI common code utility class. Used to parse the output
> +// returned from lldb commands using regex.
> +//--
> +class CRegexParser
> +{
> + public:
> + // Helper class for keeping track of regex matches.
> + class Match
> + {
> + friend CRegexParser;
> + public:
> + /* ctor */ explicit Match(size_t nmatches)
> + : m_matchStrs(nmatches), m_maxMatches(nmatches)
> + {
> + }
> + size_t
> + GetMatchCount() const
> + {
> + return m_matchStrs.size();
> + }
> + CMIUtilString
> + GetMatchAtIndex(size_t i) const
> + {
> + if (m_matchStrs.size() > i)
> + return m_matchStrs[i];
> + return CMIUtilString();
> + }
> + private:
> + CMIUtilString::VecString_t m_matchStrs;
> + const size_t m_maxMatches;
> + };
> +
> + // Methods:
> + // Compile the regular expression.
> + /* ctor */ explicit CRegexParser(const char *regexStr);
> +
> + // Free the memory used by the regular expression.
> + /* dtor */ ~CRegexParser();
> +
> + // No copies
> + CRegexParser(const CRegexParser&) = delete;
> + void operator=(CRegexParser&) = delete;
> +
> + // Return the match at the index.
> + int
> + GetMatchCount(const Match& match) const
> + {
> + if (m_isValid)
> + return match.GetMatchCount();
> + return 0;
> + }
> +
> + bool
> + IsValid() const
> + {
> + return m_isValid;
> + }
> +
> + // Match the input against the regular expression. Return an error
> + // if the number of matches is less than minMatches. If the default
> + // minMatches value of 0 is passed, an error will be returned if
> + // the number of matches is less than the maxMatches value used to
> + // initialize Match.
> + bool
> + Execute(const char *input, Match& match, size_t minMatches = 0);
> +
> + private:
> + llvm_regex_t m_emma;
> + const bool m_isValid;
> +};
> +
> +}
>
> Modified: lldb/trunk/tools/lldb-mi/MIUtilString.cpp
> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/lldb-mi/MIUtilString.cpp?rev=247899&r1=247898&r2=247899&view=diff
> ==============================================================================
> --- lldb/trunk/tools/lldb-mi/MIUtilString.cpp (original)
> +++ lldb/trunk/tools/lldb-mi/MIUtilString.cpp Thu Sep 17 11:22:30 2015
> @@ -55,6 +55,19 @@ CMIUtilString::CMIUtilString(const char
> }
>
> //++ ------------------------------------------------------------------------------------
> +// Details: CMIUtilString constructor.
> +// Type: Method.
> +// Args: vpData - Pointer to UTF8 text data.
> +// nLen - Length of string.
> +// Return: None.
> +// Throws: None.
> +//--
> +CMIUtilString::CMIUtilString(const char *vpData, size_t nLen)
> + : std::string(vpData, nLen)
> +{
> +}
> +
> +//++ ------------------------------------------------------------------------------------
> // Details: CMIUtilString assignment operator.
> // Type: Method.
> // Args: vpRhs - Pointer to UTF8 text data.
>
> Modified: lldb/trunk/tools/lldb-mi/MIUtilString.h
> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/lldb-mi/MIUtilString.h?rev=247899&r1=247898&r2=247899&view=diff
> ==============================================================================
> --- lldb/trunk/tools/lldb-mi/MIUtilString.h (original)
> +++ lldb/trunk/tools/lldb-mi/MIUtilString.h Thu Sep 17 11:22:30 2015
> @@ -44,6 +44,7 @@ class CMIUtilString : public std::string
> /* ctor */ CMIUtilString();
> /* ctor */ CMIUtilString(const char *vpData);
> /* ctor */ CMIUtilString(const char *const *vpData);
> + /* ctor */ CMIUtilString(const char *vpData, size_t nLen);
> //
> bool ExtractNumber(MIint64 &vwrNumber) const;
> CMIUtilString FindAndReplace(const CMIUtilString &vFind, const CMIUtilString &vReplaceWith) const;
>
>
> _______________________________________________
> lldb-commits mailing list
> lldb-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
More information about the lldb-commits
mailing list