2014-05-16 18:51:01 +08:00
|
|
|
//===-- MICmdCmdBreak.cpp ---------------------------------------*- C++ -*-===//
|
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2014-11-18 02:06:21 +08:00
|
|
|
// Overview: CMICmdCmdBreakInsert implementation.
|
|
|
|
// CMICmdCmdBreakDelete implementation.
|
|
|
|
// CMICmdCmdBreakDisable implementation.
|
|
|
|
// CMICmdCmdBreakEnable implementation.
|
|
|
|
// CMICmdCmdBreakAfter implementation.
|
|
|
|
// CMICmdCmdBreakCondition implementation.
|
2014-05-16 18:51:01 +08:00
|
|
|
|
|
|
|
// Third Party Headers:
|
2015-01-20 08:04:26 +08:00
|
|
|
#include "lldb/API/SBBreakpointLocation.h"
|
2014-05-16 18:51:01 +08:00
|
|
|
|
|
|
|
// In-house headers:
|
|
|
|
#include "MICmdCmdBreak.h"
|
|
|
|
#include "MICmnMIResultRecord.h"
|
|
|
|
#include "MICmnMIValueConst.h"
|
2014-06-25 00:35:50 +08:00
|
|
|
#include "MICmnMIOutOfBandRecord.h"
|
2014-05-16 18:51:01 +08:00
|
|
|
#include "MICmnLLDBDebugger.h"
|
|
|
|
#include "MICmnLLDBDebugSessionInfo.h"
|
|
|
|
#include "MICmdArgValFile.h"
|
|
|
|
#include "MICmdArgValNumber.h"
|
|
|
|
#include "MICmdArgValString.h"
|
|
|
|
#include "MICmdArgValThreadGrp.h"
|
|
|
|
#include "MICmdArgValOptionLong.h"
|
|
|
|
#include "MICmdArgValOptionShort.h"
|
|
|
|
#include "MICmdArgValListOfN.h"
|
2014-06-25 00:35:50 +08:00
|
|
|
#include "MICmnStreamStdout.h"
|
2014-05-16 18:51:01 +08:00
|
|
|
|
|
|
|
//++ ------------------------------------------------------------------------------------
|
2014-11-18 02:06:21 +08:00
|
|
|
// Details: CMICmdCmdBreakInsert constructor.
|
|
|
|
// Type: Method.
|
|
|
|
// Args: None.
|
|
|
|
// Return: None.
|
|
|
|
// Throws: None.
|
2014-05-16 18:51:01 +08:00
|
|
|
//--
|
2014-11-18 02:06:21 +08:00
|
|
|
CMICmdCmdBreakInsert::CMICmdCmdBreakInsert(void)
|
|
|
|
: m_bBrkPtIsTemp(false)
|
|
|
|
, m_bBrkPtIsPending(false)
|
|
|
|
, m_nBrkPtIgnoreCount(0)
|
|
|
|
, m_bBrkPtEnabled(false)
|
|
|
|
, m_bBrkPtCondition(false)
|
|
|
|
, m_bBrkPtThreadId(false)
|
|
|
|
, m_nBrkPtThreadId(0)
|
|
|
|
, m_constStrArgNamedTempBrkPt("t")
|
|
|
|
, m_constStrArgNamedHWBrkPt("h")
|
|
|
|
, m_constStrArgNamedPendinfBrkPt("f")
|
|
|
|
, m_constStrArgNamedDisableBrkPt("d")
|
|
|
|
, m_constStrArgNamedTracePt("a")
|
|
|
|
, m_constStrArgNamedConditionalBrkPt("c")
|
|
|
|
, m_constStrArgNamedInoreCnt("i")
|
|
|
|
, m_constStrArgNamedRestrictBrkPtToThreadId("p")
|
|
|
|
, m_constStrArgNamedLocation("location")
|
|
|
|
, m_constStrArgNamedThreadGroup("thread-group")
|
2014-05-16 18:51:01 +08:00
|
|
|
{
|
2014-11-18 02:06:21 +08:00
|
|
|
// Command factory matches this name with that received from the stdin stream
|
|
|
|
m_strMiCmd = "break-insert";
|
|
|
|
|
|
|
|
// Required by the CMICmdFactory when registering *this command
|
|
|
|
m_pSelfCreatorFn = &CMICmdCmdBreakInsert::CreateSelf;
|
2014-05-16 18:51:01 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
//++ ------------------------------------------------------------------------------------
|
2014-11-18 02:06:21 +08:00
|
|
|
// Details: CMICmdCmdBreakInsert destructor.
|
|
|
|
// Type: Overrideable.
|
|
|
|
// Args: None.
|
|
|
|
// Return: None.
|
|
|
|
// Throws: None.
|
2014-05-16 18:51:01 +08:00
|
|
|
//--
|
2014-11-18 02:06:21 +08:00
|
|
|
CMICmdCmdBreakInsert::~CMICmdCmdBreakInsert(void)
|
2014-05-16 18:51:01 +08:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
//++ ------------------------------------------------------------------------------------
|
2014-11-18 02:06:21 +08:00
|
|
|
// Details: The invoker requires this function. The parses the command line options
|
|
|
|
// arguments to extract values for each of those arguments.
|
|
|
|
// Type: Overridden.
|
|
|
|
// Args: None.
|
|
|
|
// Return: MIstatus::success - Functional succeeded.
|
|
|
|
// MIstatus::failure - Functional failed.
|
|
|
|
// Throws: None.
|
2014-05-16 18:51:01 +08:00
|
|
|
//--
|
2014-11-18 02:06:21 +08:00
|
|
|
bool
|
|
|
|
CMICmdCmdBreakInsert::ParseArgs(void)
|
2014-05-16 18:51:01 +08:00
|
|
|
{
|
2014-11-18 02:06:21 +08:00
|
|
|
bool bOk = m_setCmdArgs.Add(*(new CMICmdArgValOptionShort(m_constStrArgNamedTempBrkPt, false, true)));
|
|
|
|
// Not implemented bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValOptionShort( m_constStrArgNamedHWBrkPt, false, false ) ) );
|
|
|
|
bOk = bOk &&
|
|
|
|
m_setCmdArgs.Add(*(new CMICmdArgValOptionShort(m_constStrArgNamedPendinfBrkPt, false, true,
|
|
|
|
CMICmdArgValListBase::eArgValType_StringQuotedNumberPath, 1)));
|
|
|
|
bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValOptionShort(m_constStrArgNamedDisableBrkPt, false, false)));
|
|
|
|
// Not implemented bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValOptionShort( m_constStrArgNamedTracePt, false, false ) ) );
|
|
|
|
bOk = bOk &&
|
|
|
|
m_setCmdArgs.Add(*(new CMICmdArgValOptionShort(m_constStrArgNamedConditionalBrkPt, false, true,
|
|
|
|
CMICmdArgValListBase::eArgValType_StringQuoted, 1)));
|
|
|
|
bOk = bOk &&
|
|
|
|
m_setCmdArgs.Add(
|
|
|
|
*(new CMICmdArgValOptionShort(m_constStrArgNamedInoreCnt, false, true, CMICmdArgValListBase::eArgValType_Number, 1)));
|
|
|
|
bOk = bOk &&
|
|
|
|
m_setCmdArgs.Add(*(new CMICmdArgValOptionShort(m_constStrArgNamedRestrictBrkPtToThreadId, false, true,
|
|
|
|
CMICmdArgValListBase::eArgValType_Number, 1)));
|
|
|
|
bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValString(m_constStrArgNamedLocation, false, true)));
|
|
|
|
bOk = bOk &&
|
|
|
|
m_setCmdArgs.Add(
|
|
|
|
*(new CMICmdArgValOptionLong(m_constStrArgNamedThreadGroup, false, true, CMICmdArgValListBase::eArgValType_ThreadGrp, 1)));
|
|
|
|
return (bOk && ParseValidateCmdOptions());
|
2014-05-16 18:51:01 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
//++ ------------------------------------------------------------------------------------
|
2014-11-18 02:06:21 +08:00
|
|
|
// Details: The invoker requires this function. The command does work in this function.
|
|
|
|
// The command is likely to communicate with the LLDB SBDebugger in here.
|
|
|
|
// Type: Overridden.
|
|
|
|
// Args: None.
|
|
|
|
// Return: MIstatus::success - Functional succeeded.
|
|
|
|
// MIstatus::failure - Functional failed.
|
|
|
|
// Throws: None.
|
2014-05-16 18:51:01 +08:00
|
|
|
//--
|
2014-11-18 02:06:21 +08:00
|
|
|
bool
|
|
|
|
CMICmdCmdBreakInsert::Execute(void)
|
2014-05-16 18:51:01 +08:00
|
|
|
{
|
2014-11-18 02:06:21 +08:00
|
|
|
CMICMDBASE_GETOPTION(pArgTempBrkPt, OptionShort, m_constStrArgNamedTempBrkPt);
|
|
|
|
CMICMDBASE_GETOPTION(pArgThreadGroup, OptionLong, m_constStrArgNamedThreadGroup);
|
|
|
|
CMICMDBASE_GETOPTION(pArgLocation, String, m_constStrArgNamedLocation);
|
|
|
|
CMICMDBASE_GETOPTION(pArgIgnoreCnt, OptionShort, m_constStrArgNamedInoreCnt);
|
|
|
|
CMICMDBASE_GETOPTION(pArgPendingBrkPt, OptionShort, m_constStrArgNamedPendinfBrkPt);
|
|
|
|
CMICMDBASE_GETOPTION(pArgDisableBrkPt, OptionShort, m_constStrArgNamedDisableBrkPt);
|
|
|
|
CMICMDBASE_GETOPTION(pArgConditionalBrkPt, OptionShort, m_constStrArgNamedConditionalBrkPt);
|
|
|
|
CMICMDBASE_GETOPTION(pArgRestrictBrkPtToThreadId, OptionShort, m_constStrArgNamedRestrictBrkPtToThreadId);
|
|
|
|
|
|
|
|
m_bBrkPtEnabled = !pArgDisableBrkPt->GetFound();
|
|
|
|
m_bBrkPtIsTemp = pArgTempBrkPt->GetFound();
|
|
|
|
m_bHaveArgOptionThreadGrp = pArgThreadGroup->GetFound();
|
|
|
|
if (m_bHaveArgOptionThreadGrp)
|
|
|
|
{
|
|
|
|
MIuint nThreadGrp = 0;
|
|
|
|
pArgThreadGroup->GetExpectedOption<CMICmdArgValThreadGrp, MIuint>(nThreadGrp);
|
|
|
|
m_strArgOptionThreadGrp = CMIUtilString::Format("i%d", nThreadGrp);
|
|
|
|
}
|
|
|
|
m_bBrkPtIsPending = pArgPendingBrkPt->GetFound();
|
|
|
|
if (pArgLocation->GetFound())
|
|
|
|
m_brkName = pArgLocation->GetValue();
|
|
|
|
else if (m_bBrkPtIsPending)
|
|
|
|
{
|
|
|
|
pArgPendingBrkPt->GetExpectedOption<CMICmdArgValString, CMIUtilString>(m_brkName);
|
|
|
|
}
|
|
|
|
if (pArgIgnoreCnt->GetFound())
|
|
|
|
{
|
|
|
|
pArgIgnoreCnt->GetExpectedOption<CMICmdArgValNumber, MIuint>(m_nBrkPtIgnoreCount);
|
|
|
|
}
|
|
|
|
m_bBrkPtCondition = pArgConditionalBrkPt->GetFound();
|
|
|
|
if (m_bBrkPtCondition)
|
|
|
|
{
|
|
|
|
pArgConditionalBrkPt->GetExpectedOption<CMICmdArgValString, CMIUtilString>(m_brkPtCondition);
|
|
|
|
}
|
|
|
|
m_bBrkPtThreadId = pArgRestrictBrkPtToThreadId->GetFound();
|
|
|
|
if (m_bBrkPtCondition)
|
|
|
|
{
|
|
|
|
pArgRestrictBrkPtToThreadId->GetExpectedOption<CMICmdArgValNumber, MIuint>(m_nBrkPtThreadId);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Determine if break on a file line or at a function
|
|
|
|
BreakPoint_e eBrkPtType = eBreakPoint_NotDefineYet;
|
|
|
|
const CMIUtilString cColon = ":";
|
|
|
|
CMIUtilString fileName;
|
|
|
|
MIuint nFileLine = 0;
|
|
|
|
CMIUtilString strFileFn;
|
2015-02-09 04:21:08 +08:00
|
|
|
CMIUtilString rStrLineOrFn;
|
|
|
|
// Full path in windows can have : after drive letter. So look for the
|
|
|
|
// last colon
|
|
|
|
const size_t nPosColon = m_brkName.find_last_of(cColon);
|
|
|
|
if (nPosColon != std::string::npos)
|
2014-11-18 02:06:21 +08:00
|
|
|
{
|
2015-02-09 04:21:08 +08:00
|
|
|
// extract file name and line number from it
|
|
|
|
fileName = m_brkName.substr(0, nPosColon);
|
|
|
|
rStrLineOrFn = m_brkName.substr(nPosColon + 1, m_brkName.size() - nPosColon - 1);
|
|
|
|
|
2014-11-18 02:06:21 +08:00
|
|
|
if (rStrLineOrFn.empty())
|
|
|
|
eBrkPtType = eBreakPoint_ByName;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
MIint64 nValue = 0;
|
|
|
|
if (rStrLineOrFn.ExtractNumber(nValue))
|
|
|
|
{
|
|
|
|
nFileLine = static_cast<MIuint>(nValue);
|
|
|
|
eBrkPtType = eBreakPoint_ByFileLine;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
strFileFn = rStrLineOrFn;
|
|
|
|
eBrkPtType = eBreakPoint_ByFileFn;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Determine if break defined as an address
|
|
|
|
lldb::addr_t nAddress = 0;
|
|
|
|
if (eBrkPtType == eBreakPoint_NotDefineYet)
|
|
|
|
{
|
|
|
|
MIint64 nValue = 0;
|
|
|
|
if (m_brkName.ExtractNumber(nValue))
|
|
|
|
{
|
|
|
|
nAddress = static_cast<lldb::addr_t>(nValue);
|
|
|
|
eBrkPtType = eBreakPoint_ByAddress;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Break defined as an function
|
|
|
|
if (eBrkPtType == eBreakPoint_NotDefineYet)
|
|
|
|
{
|
|
|
|
eBrkPtType = eBreakPoint_ByName;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Ask LLDB to create a breakpoint
|
|
|
|
bool bOk = MIstatus::success;
|
|
|
|
CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
|
2015-02-03 18:05:54 +08:00
|
|
|
lldb::SBTarget sbTarget = rSessionInfo.GetTarget();
|
2014-11-18 02:06:21 +08:00
|
|
|
switch (eBrkPtType)
|
|
|
|
{
|
|
|
|
case eBreakPoint_ByAddress:
|
2015-02-03 18:05:54 +08:00
|
|
|
m_brkPt = sbTarget.BreakpointCreateByAddress(nAddress);
|
2014-11-18 02:06:21 +08:00
|
|
|
break;
|
|
|
|
case eBreakPoint_ByFileFn:
|
2015-02-03 18:05:54 +08:00
|
|
|
m_brkPt = sbTarget.BreakpointCreateByName(strFileFn.c_str(), fileName.c_str());
|
2014-11-18 02:06:21 +08:00
|
|
|
break;
|
|
|
|
case eBreakPoint_ByFileLine:
|
2015-02-03 18:05:54 +08:00
|
|
|
m_brkPt = sbTarget.BreakpointCreateByLocation(fileName.c_str(), nFileLine);
|
2014-11-18 02:06:21 +08:00
|
|
|
break;
|
|
|
|
case eBreakPoint_ByName:
|
Fix -break-insert for system functions (MI)
Summary:
# Fix -break-insert for system functions
# Fix MiExecTestCase to use -break-insert instead of CLI "b"
# Improve MiBreakTestCase: now it uses printf() instead of in-house function
All tests pass on OS X.
Test Plan:
```
$ bin/lldb-mi --interpreter
(gdb)
-file-exec-and-symbols ~/p/hello
^done
(gdb)
=shlibs-added,shlib-info=[num="1",name="hello",dyld-addr="-",reason="dyld",path="/Users/IliaK/p/hello",loaded_addr="-",dsym-objpath="/Users/IliaK/p/hello.dSYM/Contents/Resources/DWARF/hello"]
-break-insert -f printf
^done,bkpt={number="1",type="breakpoint",disp="keep",enabled="y",addr="0xffffffff",func="??",file="??",fullname="??/??",line="0",pending=["printf"],times="0",original-location="printf"}
(gdb)
=breakpoint-modified,bkpt={number="1",type="breakpoint",disp="keep",enabled="y",addr="0xffffffff",func="??",file="??",fullname="??/??",line="0",pending=["printf"],times="0",original-location="printf"}
-exec-run
^running
...
*stopped,reason="breakpoint-hit",disp="del",bkptno="1",frame={addr="0x7fff8a476910",func="printf",args=[],file="??",fullname="??",line="-1"},thread-id="1",stopped-threads="all"
(gdb)
```
Reviewers: abidh, clayborg
Reviewed By: clayborg
Subscribers: lldb-commits, clayborg, abidh
Differential Revision: http://reviews.llvm.org/D8412
llvm-svn: 232734
2015-03-20 01:13:20 +08:00
|
|
|
m_brkPt = sbTarget.BreakpointCreateByName(m_brkName.c_str(), nullptr);
|
2014-11-18 02:06:21 +08:00
|
|
|
break;
|
|
|
|
case eBreakPoint_count:
|
|
|
|
case eBreakPoint_NotDefineYet:
|
|
|
|
case eBreakPoint_Invalid:
|
|
|
|
bOk = MIstatus::failure;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (bOk)
|
|
|
|
{
|
|
|
|
m_brkPt.SetEnabled(m_bBrkPtEnabled);
|
|
|
|
m_brkPt.SetIgnoreCount(m_nBrkPtIgnoreCount);
|
|
|
|
if (m_bBrkPtCondition)
|
|
|
|
m_brkPt.SetCondition(m_brkPtCondition.c_str());
|
|
|
|
if (m_bBrkPtThreadId)
|
|
|
|
m_brkPt.SetThreadID(m_nBrkPtThreadId);
|
|
|
|
if (!m_brkPt.IsValid())
|
|
|
|
m_bBrkPtIsPending = pArgPendingBrkPt->GetFound();
|
|
|
|
}
|
|
|
|
|
|
|
|
// CODETAG_LLDB_BREAKPOINT_CREATION
|
|
|
|
// This is in the main thread
|
|
|
|
// Record break point information to be by LLDB event handler function
|
|
|
|
CMICmnLLDBDebugSessionInfo::SBrkPtInfo sBrkPtInfo;
|
|
|
|
sBrkPtInfo.m_id = m_brkPt.GetID();
|
|
|
|
sBrkPtInfo.m_bDisp = m_bBrkPtIsTemp;
|
|
|
|
sBrkPtInfo.m_bEnabled = m_bBrkPtEnabled;
|
|
|
|
sBrkPtInfo.m_bHaveArgOptionThreadGrp = m_bHaveArgOptionThreadGrp;
|
|
|
|
sBrkPtInfo.m_strOptThrdGrp = m_strArgOptionThreadGrp;
|
|
|
|
sBrkPtInfo.m_strOrigLoc = m_brkName;
|
|
|
|
sBrkPtInfo.m_nIgnore = m_nBrkPtIgnoreCount;
|
|
|
|
sBrkPtInfo.m_bPending = m_bBrkPtIsPending;
|
|
|
|
sBrkPtInfo.m_bCondition = m_bBrkPtCondition;
|
|
|
|
sBrkPtInfo.m_strCondition = m_brkPtCondition;
|
|
|
|
sBrkPtInfo.m_bBrkPtThreadId = m_bBrkPtThreadId;
|
|
|
|
sBrkPtInfo.m_nBrkPtThreadId = m_nBrkPtThreadId;
|
|
|
|
bOk = bOk && rSessionInfo.RecordBrkPtInfo(m_brkPt.GetID(), sBrkPtInfo);
|
|
|
|
|
|
|
|
if (!bOk)
|
|
|
|
{
|
|
|
|
SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_BRKPT_INVALID), m_cmdData.strMiCmd.c_str(), m_brkName.c_str()));
|
|
|
|
return MIstatus::failure;
|
|
|
|
}
|
|
|
|
|
|
|
|
// CODETAG_LLDB_BRKPT_ID_MAX
|
|
|
|
if (m_brkPt.GetID() > (lldb::break_id_t)rSessionInfo.m_nBrkPointCntMax)
|
|
|
|
{
|
|
|
|
SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_BRKPT_CNT_EXCEEDED), m_cmdData.strMiCmd.c_str(), rSessionInfo.m_nBrkPointCntMax,
|
|
|
|
m_brkName.c_str()));
|
|
|
|
return MIstatus::failure;
|
|
|
|
}
|
|
|
|
|
|
|
|
return MIstatus::success;
|
2014-05-16 18:51:01 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
//++ ------------------------------------------------------------------------------------
|
2014-11-18 02:06:21 +08:00
|
|
|
// Details: The invoker requires this function. The command prepares a MI Record Result
|
|
|
|
// for the work carried out in the Execute().
|
|
|
|
// Type: Overridden.
|
|
|
|
// Args: None.
|
|
|
|
// Return: MIstatus::success - Functional succeeded.
|
|
|
|
// MIstatus::failure - Functional failed.
|
|
|
|
// Throws: None.
|
2014-05-16 18:51:01 +08:00
|
|
|
//--
|
2014-11-18 02:06:21 +08:00
|
|
|
bool
|
|
|
|
CMICmdCmdBreakInsert::Acknowledge(void)
|
2014-05-16 18:51:01 +08:00
|
|
|
{
|
2014-11-18 02:06:21 +08:00
|
|
|
// Get breakpoint information
|
|
|
|
CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
|
|
|
|
CMICmnLLDBDebugSessionInfo::SBrkPtInfo sBrkPtInfo;
|
|
|
|
if (!rSessionInfo.GetBrkPtInfo(m_brkPt, sBrkPtInfo))
|
|
|
|
{
|
|
|
|
return MIstatus::failure;
|
|
|
|
}
|
|
|
|
|
|
|
|
// CODETAG_LLDB_BREAKPOINT_CREATION
|
|
|
|
// Add more breakpoint information or overwrite existing information
|
|
|
|
sBrkPtInfo.m_bDisp = m_bBrkPtIsTemp;
|
|
|
|
sBrkPtInfo.m_bEnabled = m_bBrkPtEnabled;
|
|
|
|
sBrkPtInfo.m_bHaveArgOptionThreadGrp = m_bHaveArgOptionThreadGrp;
|
|
|
|
sBrkPtInfo.m_strOptThrdGrp = m_strArgOptionThreadGrp;
|
2015-02-05 00:04:16 +08:00
|
|
|
sBrkPtInfo.m_nTimes = m_brkPt.GetHitCount();
|
2014-11-18 02:06:21 +08:00
|
|
|
sBrkPtInfo.m_strOrigLoc = m_brkName;
|
|
|
|
sBrkPtInfo.m_nIgnore = m_nBrkPtIgnoreCount;
|
|
|
|
sBrkPtInfo.m_bPending = m_bBrkPtIsPending;
|
|
|
|
sBrkPtInfo.m_bCondition = m_bBrkPtCondition;
|
|
|
|
sBrkPtInfo.m_strCondition = m_brkPtCondition;
|
|
|
|
sBrkPtInfo.m_bBrkPtThreadId = m_bBrkPtThreadId;
|
|
|
|
sBrkPtInfo.m_nBrkPtThreadId = m_nBrkPtThreadId;
|
|
|
|
|
|
|
|
// MI print
|
|
|
|
// "^done,bkpt={number=\"%d\",type=\"breakpoint\",disp=\"%s\",enabled=\"%c\",addr=\"0x%08x\",func=\"%s\",file=\"%s\",fullname=\"%s/%s\",line=\"%d\",thread-groups=[\"%s\"],times=\"%d\",original-location=\"%s\"}"
|
|
|
|
CMICmnMIValueTuple miValueTuple;
|
|
|
|
if (!rSessionInfo.MIResponseFormBrkPtInfo(sBrkPtInfo, miValueTuple))
|
|
|
|
{
|
|
|
|
return MIstatus::failure;
|
|
|
|
}
|
|
|
|
|
|
|
|
const CMICmnMIValueResult miValueResultD("bkpt", miValueTuple);
|
|
|
|
const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResultD);
|
|
|
|
m_miResultRecord = miRecordResult;
|
|
|
|
|
|
|
|
return MIstatus::success;
|
2014-05-16 18:51:01 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
//++ ------------------------------------------------------------------------------------
|
2014-11-18 02:06:21 +08:00
|
|
|
// Details: Required by the CMICmdFactory when registering *this command. The factory
|
|
|
|
// calls this function to create an instance of *this command.
|
|
|
|
// Type: Static method.
|
|
|
|
// Args: None.
|
|
|
|
// Return: CMICmdBase * - Pointer to a new command.
|
|
|
|
// Throws: None.
|
2014-05-16 18:51:01 +08:00
|
|
|
//--
|
2014-11-18 02:06:21 +08:00
|
|
|
CMICmdBase *
|
|
|
|
CMICmdCmdBreakInsert::CreateSelf(void)
|
2014-05-16 18:51:01 +08:00
|
|
|
{
|
2014-11-18 02:06:21 +08:00
|
|
|
return new CMICmdCmdBreakInsert();
|
2014-05-16 18:51:01 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------
|
|
|
|
//---------------------------------------------------------------------------------------
|
|
|
|
//---------------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
//++ ------------------------------------------------------------------------------------
|
2014-11-18 02:06:21 +08:00
|
|
|
// Details: CMICmdCmdBreakDelete constructor.
|
|
|
|
// Type: Method.
|
|
|
|
// Args: None.
|
|
|
|
// Return: None.
|
|
|
|
// Throws: None.
|
2014-05-16 18:51:01 +08:00
|
|
|
//--
|
2014-11-18 02:06:21 +08:00
|
|
|
CMICmdCmdBreakDelete::CMICmdCmdBreakDelete(void)
|
|
|
|
: m_constStrArgNamedBrkPt("breakpoint")
|
|
|
|
, m_constStrArgNamedThreadGrp("thread-group")
|
2014-05-16 18:51:01 +08:00
|
|
|
{
|
2014-11-18 02:06:21 +08:00
|
|
|
// Command factory matches this name with that received from the stdin stream
|
|
|
|
m_strMiCmd = "break-delete";
|
|
|
|
|
|
|
|
// Required by the CMICmdFactory when registering *this command
|
|
|
|
m_pSelfCreatorFn = &CMICmdCmdBreakDelete::CreateSelf;
|
2014-05-16 18:51:01 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
//++ ------------------------------------------------------------------------------------
|
2014-11-18 02:06:21 +08:00
|
|
|
// Details: CMICmdCmdBreakDelete destructor.
|
|
|
|
// Type: Overrideable.
|
|
|
|
// Args: None.
|
|
|
|
// Return: None.
|
|
|
|
// Throws: None.
|
2014-05-16 18:51:01 +08:00
|
|
|
//--
|
2014-11-18 02:06:21 +08:00
|
|
|
CMICmdCmdBreakDelete::~CMICmdCmdBreakDelete(void)
|
2014-05-16 18:51:01 +08:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
//++ ------------------------------------------------------------------------------------
|
2014-11-18 02:06:21 +08:00
|
|
|
// Details: The invoker requires this function. The parses the command line options
|
|
|
|
// arguments to extract values for each of those arguments.
|
|
|
|
// Type: Overridden.
|
|
|
|
// Args: None.
|
|
|
|
// Return: MIstatus::success - Functional succeeded.
|
|
|
|
// MIstatus::failure - Functional failed.
|
|
|
|
// Throws: None.
|
2014-05-16 18:51:01 +08:00
|
|
|
//--
|
2014-11-18 02:06:21 +08:00
|
|
|
bool
|
|
|
|
CMICmdCmdBreakDelete::ParseArgs(void)
|
2014-05-16 18:51:01 +08:00
|
|
|
{
|
2014-11-18 02:06:21 +08:00
|
|
|
bool bOk = m_setCmdArgs.Add(
|
|
|
|
*(new CMICmdArgValOptionLong(m_constStrArgNamedThreadGrp, false, false, CMICmdArgValListBase::eArgValType_ThreadGrp, 1)));
|
|
|
|
bOk =
|
|
|
|
bOk && m_setCmdArgs.Add(*(new CMICmdArgValListOfN(m_constStrArgNamedBrkPt, true, true, CMICmdArgValListBase::eArgValType_Number)));
|
|
|
|
return (bOk && ParseValidateCmdOptions());
|
2014-05-16 18:51:01 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
//++ ------------------------------------------------------------------------------------
|
2014-11-18 02:06:21 +08:00
|
|
|
// Details: The invoker requires this function. The command does work in this function.
|
|
|
|
// The command is likely to communicate with the LLDB SBDebugger in here.
|
|
|
|
// Type: Overridden.
|
|
|
|
// Args: None.
|
|
|
|
// Return: MIstatus::success - Functional succeeded.
|
|
|
|
// MIstatus::failure - Functional failed.
|
|
|
|
// Throws: None.
|
2014-05-16 18:51:01 +08:00
|
|
|
//--
|
2014-11-18 02:06:21 +08:00
|
|
|
bool
|
|
|
|
CMICmdCmdBreakDelete::Execute(void)
|
2014-05-16 18:51:01 +08:00
|
|
|
{
|
2014-11-18 02:06:21 +08:00
|
|
|
CMICMDBASE_GETOPTION(pArgBrkPt, ListOfN, m_constStrArgNamedBrkPt);
|
|
|
|
|
|
|
|
// ATM we only handle one break point ID
|
|
|
|
MIuint64 nBrk = UINT64_MAX;
|
|
|
|
if (!pArgBrkPt->GetExpectedOption<CMICmdArgValNumber, MIuint64>(nBrk))
|
|
|
|
{
|
|
|
|
SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_BRKPT_INVALID), m_cmdData.strMiCmd.c_str(), m_constStrArgNamedBrkPt.c_str()));
|
|
|
|
return MIstatus::failure;
|
|
|
|
}
|
|
|
|
|
|
|
|
CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
|
2015-02-03 18:05:54 +08:00
|
|
|
const bool bBrkPt = rSessionInfo.GetTarget().BreakpointDelete(static_cast<lldb::break_id_t>(nBrk));
|
2014-11-18 02:06:21 +08:00
|
|
|
if (!bBrkPt)
|
|
|
|
{
|
|
|
|
const CMIUtilString strBrkNum(CMIUtilString::Format("%d", nBrk));
|
|
|
|
SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_BRKPT_INVALID), m_cmdData.strMiCmd.c_str(), strBrkNum.c_str()));
|
|
|
|
return MIstatus::failure;
|
|
|
|
}
|
|
|
|
|
|
|
|
return MIstatus::success;
|
2014-05-16 18:51:01 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
//++ ------------------------------------------------------------------------------------
|
2014-11-18 02:06:21 +08:00
|
|
|
// Details: The invoker requires this function. The command prepares a MI Record Result
|
|
|
|
// for the work carried out in the Execute().
|
|
|
|
// Type: Overridden.
|
|
|
|
// Args: None.
|
|
|
|
// Return: MIstatus::success - Functional succeeded.
|
|
|
|
// MIstatus::failure - Functional failed.
|
|
|
|
// Throws: None.
|
2014-05-16 18:51:01 +08:00
|
|
|
//--
|
2014-11-18 02:06:21 +08:00
|
|
|
bool
|
|
|
|
CMICmdCmdBreakDelete::Acknowledge(void)
|
2014-05-16 18:51:01 +08:00
|
|
|
{
|
2014-11-18 02:06:21 +08:00
|
|
|
const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done);
|
|
|
|
m_miResultRecord = miRecordResult;
|
2014-05-16 18:51:01 +08:00
|
|
|
|
2014-11-18 02:06:21 +08:00
|
|
|
return MIstatus::success;
|
2014-05-16 18:51:01 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
//++ ------------------------------------------------------------------------------------
|
2014-11-18 02:06:21 +08:00
|
|
|
// Details: Required by the CMICmdFactory when registering *this command. The factory
|
|
|
|
// calls this function to create an instance of *this command.
|
|
|
|
// Type: Static method.
|
|
|
|
// Args: None.
|
|
|
|
// Return: CMICmdBase * - Pointer to a new command.
|
|
|
|
// Throws: None.
|
2014-05-16 18:51:01 +08:00
|
|
|
//--
|
2014-11-18 02:06:21 +08:00
|
|
|
CMICmdBase *
|
|
|
|
CMICmdCmdBreakDelete::CreateSelf(void)
|
2014-05-16 18:51:01 +08:00
|
|
|
{
|
2014-11-18 02:06:21 +08:00
|
|
|
return new CMICmdCmdBreakDelete();
|
2014-05-16 18:51:01 +08:00
|
|
|
}
|
2014-06-25 00:35:50 +08:00
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------
|
|
|
|
//---------------------------------------------------------------------------------------
|
|
|
|
//---------------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
//++ ------------------------------------------------------------------------------------
|
2014-11-18 02:06:21 +08:00
|
|
|
// Details: CMICmdCmdBreakDisable constructor.
|
|
|
|
// Type: Method.
|
|
|
|
// Args: None.
|
|
|
|
// Return: None.
|
|
|
|
// Throws: None.
|
2014-06-25 00:35:50 +08:00
|
|
|
//--
|
2014-11-18 02:06:21 +08:00
|
|
|
CMICmdCmdBreakDisable::CMICmdCmdBreakDisable(void)
|
|
|
|
: m_constStrArgNamedThreadGrp("thread-group")
|
|
|
|
, m_constStrArgNamedBrkPt("breakpoint")
|
|
|
|
, m_bBrkPtDisabledOk(false)
|
|
|
|
, m_nBrkPtId(0)
|
2014-06-25 00:35:50 +08:00
|
|
|
{
|
2014-11-18 02:06:21 +08:00
|
|
|
// Command factory matches this name with that received from the stdin stream
|
|
|
|
m_strMiCmd = "break-disable";
|
|
|
|
|
|
|
|
// Required by the CMICmdFactory when registering *this command
|
|
|
|
m_pSelfCreatorFn = &CMICmdCmdBreakDisable::CreateSelf;
|
2014-06-25 00:35:50 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
//++ ------------------------------------------------------------------------------------
|
2014-11-18 02:06:21 +08:00
|
|
|
// Details: CMICmdCmdBreakDisable destructor.
|
|
|
|
// Type: Overrideable.
|
|
|
|
// Args: None.
|
|
|
|
// Return: None.
|
|
|
|
// Throws: None.
|
2014-06-25 00:35:50 +08:00
|
|
|
//--
|
2014-11-18 02:06:21 +08:00
|
|
|
CMICmdCmdBreakDisable::~CMICmdCmdBreakDisable(void)
|
2014-06-25 00:35:50 +08:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
//++ ------------------------------------------------------------------------------------
|
2014-11-18 02:06:21 +08:00
|
|
|
// Details: The invoker requires this function. The parses the command line options
|
|
|
|
// arguments to extract values for each of those arguments.
|
|
|
|
// Type: Overridden.
|
|
|
|
// Args: None.
|
|
|
|
// Return: MIstatus::success - Functional succeeded.
|
|
|
|
// MIstatus::failure - Functional failed.
|
|
|
|
// Throws: None.
|
2014-06-25 00:35:50 +08:00
|
|
|
//--
|
2014-11-18 02:06:21 +08:00
|
|
|
bool
|
|
|
|
CMICmdCmdBreakDisable::ParseArgs(void)
|
2014-06-25 00:35:50 +08:00
|
|
|
{
|
2014-11-18 02:06:21 +08:00
|
|
|
bool bOk = m_setCmdArgs.Add(
|
|
|
|
*(new CMICmdArgValOptionLong(m_constStrArgNamedThreadGrp, false, false, CMICmdArgValListBase::eArgValType_ThreadGrp, 1)));
|
|
|
|
bOk =
|
|
|
|
bOk && m_setCmdArgs.Add(*(new CMICmdArgValListOfN(m_constStrArgNamedBrkPt, true, true, CMICmdArgValListBase::eArgValType_Number)));
|
|
|
|
return (bOk && ParseValidateCmdOptions());
|
2014-06-25 00:35:50 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
//++ ------------------------------------------------------------------------------------
|
2014-11-18 02:06:21 +08:00
|
|
|
// Details: The invoker requires this function. The command does work in this function.
|
|
|
|
// The command is likely to communicate with the LLDB SBDebugger in here.
|
|
|
|
// Type: Overridden.
|
|
|
|
// Args: None.
|
|
|
|
// Return: MIstatus::success - Functional succeeded.
|
|
|
|
// MIstatus::failure - Functional failed.
|
|
|
|
// Throws: None.
|
2014-06-25 00:35:50 +08:00
|
|
|
//--
|
2014-11-18 02:06:21 +08:00
|
|
|
bool
|
|
|
|
CMICmdCmdBreakDisable::Execute(void)
|
2014-06-25 00:35:50 +08:00
|
|
|
{
|
2014-11-18 02:06:21 +08:00
|
|
|
CMICMDBASE_GETOPTION(pArgBrkPt, ListOfN, m_constStrArgNamedBrkPt);
|
|
|
|
|
|
|
|
// ATM we only handle one break point ID
|
|
|
|
MIuint64 nBrk = UINT64_MAX;
|
|
|
|
if (!pArgBrkPt->GetExpectedOption<CMICmdArgValNumber, MIuint64>(nBrk))
|
|
|
|
{
|
|
|
|
SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_BRKPT_INVALID), m_cmdData.strMiCmd.c_str(), m_constStrArgNamedBrkPt.c_str()));
|
|
|
|
return MIstatus::failure;
|
|
|
|
}
|
|
|
|
|
|
|
|
CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
|
2015-02-03 18:05:54 +08:00
|
|
|
lldb::SBBreakpoint brkPt = rSessionInfo.GetTarget().FindBreakpointByID(static_cast<lldb::break_id_t>(nBrk));
|
2014-11-18 02:06:21 +08:00
|
|
|
if (brkPt.IsValid())
|
|
|
|
{
|
|
|
|
m_bBrkPtDisabledOk = true;
|
|
|
|
brkPt.SetEnabled(false);
|
|
|
|
m_nBrkPtId = nBrk;
|
|
|
|
}
|
|
|
|
|
|
|
|
return MIstatus::success;
|
2014-06-25 00:35:50 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
//++ ------------------------------------------------------------------------------------
|
2014-11-18 02:06:21 +08:00
|
|
|
// Details: The invoker requires this function. The command prepares a MI Record Result
|
|
|
|
// for the work carried out in the Execute().
|
|
|
|
// Type: Overridden.
|
|
|
|
// Args: None.
|
|
|
|
// Return: MIstatus::success - Functional succeeded.
|
|
|
|
// MIstatus::failure - Functional failed.
|
|
|
|
// Throws: None.
|
2014-06-25 00:35:50 +08:00
|
|
|
//--
|
2014-11-18 02:06:21 +08:00
|
|
|
bool
|
|
|
|
CMICmdCmdBreakDisable::Acknowledge(void)
|
2014-06-25 00:35:50 +08:00
|
|
|
{
|
2014-11-18 02:06:21 +08:00
|
|
|
if (m_bBrkPtDisabledOk)
|
|
|
|
{
|
|
|
|
const CMICmnMIValueConst miValueConst(CMIUtilString::Format("%d", m_nBrkPtId));
|
|
|
|
const CMICmnMIValueResult miValueResult("number", miValueConst);
|
|
|
|
CMICmnMIValueTuple miValueTuple(miValueResult);
|
|
|
|
const CMICmnMIValueConst miValueConst2("n");
|
|
|
|
const CMICmnMIValueResult miValueResult2("enabled", miValueConst2);
|
|
|
|
bool bOk = miValueTuple.Add(miValueResult2);
|
|
|
|
const CMICmnMIValueResult miValueResult3("bkpt", miValueTuple);
|
|
|
|
const CMICmnMIOutOfBandRecord miOutOfBandRecord(CMICmnMIOutOfBandRecord::eOutOfBand_BreakPointModified, miValueResult3);
|
|
|
|
bOk = bOk && CMICmnStreamStdout::TextToStdout(miOutOfBandRecord.GetString());
|
|
|
|
|
|
|
|
const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done);
|
|
|
|
m_miResultRecord = miRecordResult;
|
|
|
|
return bOk;
|
|
|
|
}
|
|
|
|
|
|
|
|
const CMIUtilString strBrkPtId(CMIUtilString::Format("%d", m_nBrkPtId));
|
|
|
|
const CMICmnMIValueConst miValueConst(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_BRKPT_INVALID), strBrkPtId.c_str()));
|
|
|
|
const CMICmnMIValueResult miValueResult("msg", miValueConst);
|
|
|
|
const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult);
|
|
|
|
m_miResultRecord = miRecordResult;
|
|
|
|
|
|
|
|
return MIstatus::success;
|
2014-06-25 00:35:50 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
//++ ------------------------------------------------------------------------------------
|
2014-11-18 02:06:21 +08:00
|
|
|
// Details: Required by the CMICmdFactory when registering *this command. The factory
|
|
|
|
// calls this function to create an instance of *this command.
|
|
|
|
// Type: Static method.
|
|
|
|
// Args: None.
|
|
|
|
// Return: CMICmdBase * - Pointer to a new command.
|
|
|
|
// Throws: None.
|
2014-06-25 00:35:50 +08:00
|
|
|
//--
|
2014-11-18 02:06:21 +08:00
|
|
|
CMICmdBase *
|
|
|
|
CMICmdCmdBreakDisable::CreateSelf(void)
|
2014-06-25 00:35:50 +08:00
|
|
|
{
|
2014-11-18 02:06:21 +08:00
|
|
|
return new CMICmdCmdBreakDisable();
|
2014-06-25 00:35:50 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------
|
|
|
|
//---------------------------------------------------------------------------------------
|
|
|
|
//---------------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
//++ ------------------------------------------------------------------------------------
|
2014-11-18 02:06:21 +08:00
|
|
|
// Details: CMICmdCmdBreakEnable constructor.
|
|
|
|
// Type: Method.
|
|
|
|
// Args: None.
|
|
|
|
// Return: None.
|
|
|
|
// Throws: None.
|
2014-06-25 00:35:50 +08:00
|
|
|
//--
|
2014-11-18 02:06:21 +08:00
|
|
|
CMICmdCmdBreakEnable::CMICmdCmdBreakEnable(void)
|
|
|
|
: m_constStrArgNamedThreadGrp("thread-group")
|
|
|
|
, m_constStrArgNamedBrkPt("breakpoint")
|
|
|
|
, m_bBrkPtEnabledOk(false)
|
|
|
|
, m_nBrkPtId(0)
|
2014-06-25 00:35:50 +08:00
|
|
|
{
|
2014-11-18 02:06:21 +08:00
|
|
|
// Command factory matches this name with that received from the stdin stream
|
|
|
|
m_strMiCmd = "break-enable";
|
|
|
|
|
|
|
|
// Required by the CMICmdFactory when registering *this command
|
|
|
|
m_pSelfCreatorFn = &CMICmdCmdBreakEnable::CreateSelf;
|
2014-06-25 00:35:50 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
//++ ------------------------------------------------------------------------------------
|
2014-11-18 02:06:21 +08:00
|
|
|
// Details: CMICmdCmdBreakEnable destructor.
|
|
|
|
// Type: Overrideable.
|
|
|
|
// Args: None.
|
|
|
|
// Return: None.
|
|
|
|
// Throws: None.
|
2014-06-25 00:35:50 +08:00
|
|
|
//--
|
2014-11-18 02:06:21 +08:00
|
|
|
CMICmdCmdBreakEnable::~CMICmdCmdBreakEnable(void)
|
2014-06-25 00:35:50 +08:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
//++ ------------------------------------------------------------------------------------
|
2014-11-18 02:06:21 +08:00
|
|
|
// Details: The invoker requires this function. The parses the command line options
|
|
|
|
// arguments to extract values for each of those arguments.
|
|
|
|
// Type: Overridden.
|
|
|
|
// Args: None.
|
|
|
|
// Return: MIstatus::success - Functional succeeded.
|
|
|
|
// MIstatus::failure - Functional failed.
|
|
|
|
// Throws: None.
|
2014-06-25 00:35:50 +08:00
|
|
|
//--
|
2014-11-18 02:06:21 +08:00
|
|
|
bool
|
|
|
|
CMICmdCmdBreakEnable::ParseArgs(void)
|
2014-06-25 00:35:50 +08:00
|
|
|
{
|
2014-11-18 02:06:21 +08:00
|
|
|
bool bOk = m_setCmdArgs.Add(
|
|
|
|
*(new CMICmdArgValOptionLong(m_constStrArgNamedThreadGrp, false, false, CMICmdArgValListBase::eArgValType_ThreadGrp, 1)));
|
|
|
|
bOk =
|
|
|
|
bOk && m_setCmdArgs.Add(*(new CMICmdArgValListOfN(m_constStrArgNamedBrkPt, true, true, CMICmdArgValListBase::eArgValType_Number)));
|
|
|
|
return (bOk && ParseValidateCmdOptions());
|
2014-06-25 00:35:50 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
//++ ------------------------------------------------------------------------------------
|
2014-11-18 02:06:21 +08:00
|
|
|
// Details: The invoker requires this function. The command does work in this function.
|
|
|
|
// The command is likely to communicate with the LLDB SBDebugger in here.
|
|
|
|
// Type: Overridden.
|
|
|
|
// Args: None.
|
|
|
|
// Return: MIstatus::success - Functional succeeded.
|
|
|
|
// MIstatus::failure - Functional failed.
|
|
|
|
// Throws: None.
|
2014-06-25 00:35:50 +08:00
|
|
|
//--
|
2014-11-18 02:06:21 +08:00
|
|
|
bool
|
|
|
|
CMICmdCmdBreakEnable::Execute(void)
|
2014-06-25 00:35:50 +08:00
|
|
|
{
|
2014-11-18 02:06:21 +08:00
|
|
|
CMICMDBASE_GETOPTION(pArgBrkPt, ListOfN, m_constStrArgNamedBrkPt);
|
|
|
|
|
|
|
|
// ATM we only handle one break point ID
|
|
|
|
MIuint64 nBrk = UINT64_MAX;
|
|
|
|
if (!pArgBrkPt->GetExpectedOption<CMICmdArgValNumber, MIuint64>(nBrk))
|
|
|
|
{
|
|
|
|
SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_BRKPT_INVALID), m_cmdData.strMiCmd.c_str(), m_constStrArgNamedBrkPt.c_str()));
|
|
|
|
return MIstatus::failure;
|
|
|
|
}
|
|
|
|
|
|
|
|
CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
|
2015-02-03 18:05:54 +08:00
|
|
|
lldb::SBBreakpoint brkPt = rSessionInfo.GetTarget().FindBreakpointByID(static_cast<lldb::break_id_t>(nBrk));
|
2014-11-18 02:06:21 +08:00
|
|
|
if (brkPt.IsValid())
|
|
|
|
{
|
|
|
|
m_bBrkPtEnabledOk = true;
|
|
|
|
brkPt.SetEnabled(false);
|
|
|
|
m_nBrkPtId = nBrk;
|
|
|
|
}
|
|
|
|
|
|
|
|
return MIstatus::success;
|
2014-06-25 00:35:50 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
//++ ------------------------------------------------------------------------------------
|
2014-11-18 02:06:21 +08:00
|
|
|
// Details: The invoker requires this function. The command prepares a MI Record Result
|
|
|
|
// for the work carried out in the Execute().
|
|
|
|
// Type: Overridden.
|
|
|
|
// Args: None.
|
|
|
|
// Return: MIstatus::success - Functional succeeded.
|
|
|
|
// MIstatus::failure - Functional failed.
|
|
|
|
// Throws: None.
|
2014-06-25 00:35:50 +08:00
|
|
|
//--
|
2014-11-18 02:06:21 +08:00
|
|
|
bool
|
|
|
|
CMICmdCmdBreakEnable::Acknowledge(void)
|
2014-06-25 00:35:50 +08:00
|
|
|
{
|
2014-11-18 02:06:21 +08:00
|
|
|
if (m_bBrkPtEnabledOk)
|
|
|
|
{
|
|
|
|
const CMICmnMIValueConst miValueConst(CMIUtilString::Format("%d", m_nBrkPtId));
|
|
|
|
const CMICmnMIValueResult miValueResult("number", miValueConst);
|
|
|
|
CMICmnMIValueTuple miValueTuple(miValueResult);
|
|
|
|
const CMICmnMIValueConst miValueConst2("y");
|
|
|
|
const CMICmnMIValueResult miValueResult2("enabled", miValueConst2);
|
|
|
|
bool bOk = miValueTuple.Add(miValueResult2);
|
|
|
|
const CMICmnMIValueResult miValueResult3("bkpt", miValueTuple);
|
|
|
|
const CMICmnMIOutOfBandRecord miOutOfBandRecord(CMICmnMIOutOfBandRecord::eOutOfBand_BreakPointModified, miValueResult3);
|
|
|
|
bOk = bOk && CMICmnStreamStdout::TextToStdout(miOutOfBandRecord.GetString());
|
|
|
|
|
|
|
|
const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done);
|
|
|
|
m_miResultRecord = miRecordResult;
|
|
|
|
return bOk;
|
|
|
|
}
|
|
|
|
|
|
|
|
const CMIUtilString strBrkPtId(CMIUtilString::Format("%d", m_nBrkPtId));
|
|
|
|
const CMICmnMIValueConst miValueConst(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_BRKPT_INVALID), strBrkPtId.c_str()));
|
|
|
|
const CMICmnMIValueResult miValueResult("msg", miValueConst);
|
|
|
|
const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult);
|
|
|
|
m_miResultRecord = miRecordResult;
|
|
|
|
|
|
|
|
return MIstatus::success;
|
2014-06-25 00:35:50 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
//++ ------------------------------------------------------------------------------------
|
2014-11-18 02:06:21 +08:00
|
|
|
// Details: Required by the CMICmdFactory when registering *this command. The factory
|
|
|
|
// calls this function to create an instance of *this command.
|
|
|
|
// Type: Static method.
|
|
|
|
// Args: None.
|
|
|
|
// Return: CMICmdBase * - Pointer to a new command.
|
|
|
|
// Throws: None.
|
2014-06-25 00:35:50 +08:00
|
|
|
//--
|
2014-11-18 02:06:21 +08:00
|
|
|
CMICmdBase *
|
|
|
|
CMICmdCmdBreakEnable::CreateSelf(void)
|
2014-06-25 00:35:50 +08:00
|
|
|
{
|
2014-11-18 02:06:21 +08:00
|
|
|
return new CMICmdCmdBreakEnable();
|
2014-06-25 00:35:50 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------
|
|
|
|
//---------------------------------------------------------------------------------------
|
|
|
|
//---------------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
//++ ------------------------------------------------------------------------------------
|
2014-11-18 02:06:21 +08:00
|
|
|
// Details: CMICmdCmdBreakAfter constructor.
|
|
|
|
// Type: Method.
|
|
|
|
// Args: None.
|
|
|
|
// Return: None.
|
|
|
|
// Throws: None.
|
2014-06-25 00:35:50 +08:00
|
|
|
//--
|
2014-11-18 02:06:21 +08:00
|
|
|
CMICmdCmdBreakAfter::CMICmdCmdBreakAfter(void)
|
|
|
|
: m_constStrArgNamedThreadGrp("thread-group")
|
|
|
|
, m_constStrArgNamedNumber("number")
|
|
|
|
, m_constStrArgNamedCount("count")
|
|
|
|
, m_nBrkPtId(0)
|
|
|
|
, m_nBrkPtCount(0)
|
2014-06-25 00:35:50 +08:00
|
|
|
{
|
2014-11-18 02:06:21 +08:00
|
|
|
// Command factory matches this name with that received from the stdin stream
|
|
|
|
m_strMiCmd = "break-after";
|
|
|
|
|
|
|
|
// Required by the CMICmdFactory when registering *this command
|
|
|
|
m_pSelfCreatorFn = &CMICmdCmdBreakAfter::CreateSelf;
|
2014-06-25 00:35:50 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
//++ ------------------------------------------------------------------------------------
|
2014-11-18 02:06:21 +08:00
|
|
|
// Details: CMICmdCmdBreakAfter destructor.
|
|
|
|
// Type: Overrideable.
|
|
|
|
// Args: None.
|
|
|
|
// Return: None.
|
|
|
|
// Throws: None.
|
2014-06-25 00:35:50 +08:00
|
|
|
//--
|
2014-11-18 02:06:21 +08:00
|
|
|
CMICmdCmdBreakAfter::~CMICmdCmdBreakAfter(void)
|
2014-06-25 00:35:50 +08:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
//++ ------------------------------------------------------------------------------------
|
2014-11-18 02:06:21 +08:00
|
|
|
// Details: The invoker requires this function. The parses the command line options
|
|
|
|
// arguments to extract values for each of those arguments.
|
|
|
|
// Type: Overridden.
|
|
|
|
// Args: None.
|
|
|
|
// Return: MIstatus::success - Functional succeeded.
|
|
|
|
// MIstatus::failure - Functional failed.
|
|
|
|
// Throws: None.
|
2014-06-25 00:35:50 +08:00
|
|
|
//--
|
2014-11-18 02:06:21 +08:00
|
|
|
bool
|
|
|
|
CMICmdCmdBreakAfter::ParseArgs(void)
|
2014-06-25 00:35:50 +08:00
|
|
|
{
|
2014-11-18 02:06:21 +08:00
|
|
|
bool bOk = m_setCmdArgs.Add(
|
|
|
|
*(new CMICmdArgValOptionLong(m_constStrArgNamedThreadGrp, false, false, CMICmdArgValListBase::eArgValType_ThreadGrp, 1)));
|
|
|
|
bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValNumber(m_constStrArgNamedNumber, true, true)));
|
|
|
|
bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValNumber(m_constStrArgNamedCount, true, true)));
|
|
|
|
return (bOk && ParseValidateCmdOptions());
|
2014-06-25 00:35:50 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
//++ ------------------------------------------------------------------------------------
|
2014-11-18 02:06:21 +08:00
|
|
|
// Details: The invoker requires this function. The command does work in this function.
|
|
|
|
// The command is likely to communicate with the LLDB SBDebugger in here.
|
|
|
|
// Type: Overridden.
|
|
|
|
// Args: None.
|
|
|
|
// Return: MIstatus::success - Functional succeeded.
|
|
|
|
// MIstatus::failure - Functional failed.
|
|
|
|
// Throws: None.
|
2014-06-25 00:35:50 +08:00
|
|
|
//--
|
2014-11-18 02:06:21 +08:00
|
|
|
bool
|
|
|
|
CMICmdCmdBreakAfter::Execute(void)
|
2014-06-25 00:35:50 +08:00
|
|
|
{
|
2014-11-18 02:06:21 +08:00
|
|
|
CMICMDBASE_GETOPTION(pArgNumber, Number, m_constStrArgNamedNumber);
|
|
|
|
CMICMDBASE_GETOPTION(pArgCount, Number, m_constStrArgNamedCount);
|
|
|
|
|
|
|
|
m_nBrkPtId = pArgNumber->GetValue();
|
|
|
|
m_nBrkPtCount = pArgCount->GetValue();
|
|
|
|
|
|
|
|
CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
|
2015-02-03 18:05:54 +08:00
|
|
|
lldb::SBBreakpoint brkPt = rSessionInfo.GetTarget().FindBreakpointByID(static_cast<lldb::break_id_t>(m_nBrkPtId));
|
2014-11-18 02:06:21 +08:00
|
|
|
if (brkPt.IsValid())
|
|
|
|
{
|
|
|
|
brkPt.SetIgnoreCount(m_nBrkPtCount);
|
|
|
|
|
|
|
|
CMICmnLLDBDebugSessionInfo::SBrkPtInfo sBrkPtInfo;
|
|
|
|
if (!rSessionInfo.RecordBrkPtInfoGet(m_nBrkPtId, sBrkPtInfo))
|
|
|
|
{
|
|
|
|
SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_BRKPT_INFO_OBJ_NOT_FOUND), m_cmdData.strMiCmd.c_str(), m_nBrkPtId));
|
|
|
|
return MIstatus::failure;
|
|
|
|
}
|
|
|
|
sBrkPtInfo.m_nIgnore = m_nBrkPtCount;
|
|
|
|
rSessionInfo.RecordBrkPtInfo(m_nBrkPtId, sBrkPtInfo);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
const CMIUtilString strBrkPtId(CMIUtilString::Format("%d", m_nBrkPtId));
|
|
|
|
SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_BRKPT_INVALID), m_cmdData.strMiCmd.c_str(), strBrkPtId.c_str()));
|
|
|
|
return MIstatus::failure;
|
|
|
|
}
|
|
|
|
|
|
|
|
return MIstatus::success;
|
2014-06-25 00:35:50 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
//++ ------------------------------------------------------------------------------------
|
2014-11-18 02:06:21 +08:00
|
|
|
// Details: The invoker requires this function. The command prepares a MI Record Result
|
|
|
|
// for the work carried out in the Execute().
|
|
|
|
// Type: Overridden.
|
|
|
|
// Args: None.
|
|
|
|
// Return: MIstatus::success - Functional succeeded.
|
|
|
|
// MIstatus::failure - Functional failed.
|
|
|
|
// Throws: None.
|
2014-06-25 00:35:50 +08:00
|
|
|
//--
|
2014-11-18 02:06:21 +08:00
|
|
|
bool
|
|
|
|
CMICmdCmdBreakAfter::Acknowledge(void)
|
2014-06-25 00:35:50 +08:00
|
|
|
{
|
2014-11-18 02:06:21 +08:00
|
|
|
const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done);
|
|
|
|
m_miResultRecord = miRecordResult;
|
2014-06-25 00:35:50 +08:00
|
|
|
|
2014-11-18 02:06:21 +08:00
|
|
|
return MIstatus::success;
|
2014-06-25 00:35:50 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
//++ ------------------------------------------------------------------------------------
|
2014-11-18 02:06:21 +08:00
|
|
|
// Details: Required by the CMICmdFactory when registering *this command. The factory
|
|
|
|
// calls this function to create an instance of *this command.
|
|
|
|
// Type: Static method.
|
|
|
|
// Args: None.
|
|
|
|
// Return: CMICmdBase * - Pointer to a new command.
|
|
|
|
// Throws: None.
|
2014-06-25 00:35:50 +08:00
|
|
|
//--
|
2014-11-18 02:06:21 +08:00
|
|
|
CMICmdBase *
|
|
|
|
CMICmdCmdBreakAfter::CreateSelf(void)
|
2014-06-25 00:35:50 +08:00
|
|
|
{
|
2014-11-18 02:06:21 +08:00
|
|
|
return new CMICmdCmdBreakAfter();
|
2014-06-25 00:35:50 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------
|
|
|
|
//---------------------------------------------------------------------------------------
|
|
|
|
//---------------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
//++ ------------------------------------------------------------------------------------
|
2014-11-18 02:06:21 +08:00
|
|
|
// Details: CMICmdCmdBreakCondition constructor.
|
|
|
|
// Type: Method.
|
|
|
|
// Args: None.
|
|
|
|
// Return: None.
|
|
|
|
// Throws: None.
|
2014-06-25 00:35:50 +08:00
|
|
|
//--
|
2014-11-18 02:06:21 +08:00
|
|
|
CMICmdCmdBreakCondition::CMICmdCmdBreakCondition(void)
|
|
|
|
: m_constStrArgNamedThreadGrp("thread-group")
|
|
|
|
, m_constStrArgNamedNumber("number")
|
|
|
|
, m_constStrArgNamedExpr("expr")
|
|
|
|
, m_constStrArgNamedExprNoQuotes(
|
|
|
|
"expression not surround by quotes") // Not specified in MI spec, we need to handle expressions not surrounded by quotes
|
|
|
|
, m_nBrkPtId(0)
|
2014-06-25 00:35:50 +08:00
|
|
|
{
|
2014-11-18 02:06:21 +08:00
|
|
|
// Command factory matches this name with that received from the stdin stream
|
|
|
|
m_strMiCmd = "break-condition";
|
|
|
|
|
|
|
|
// Required by the CMICmdFactory when registering *this command
|
|
|
|
m_pSelfCreatorFn = &CMICmdCmdBreakCondition::CreateSelf;
|
2014-06-25 00:35:50 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
//++ ------------------------------------------------------------------------------------
|
2014-11-18 02:06:21 +08:00
|
|
|
// Details: CMICmdCmdBreakCondition destructor.
|
|
|
|
// Type: Overrideable.
|
|
|
|
// Args: None.
|
|
|
|
// Return: None.
|
|
|
|
// Throws: None.
|
2014-06-25 00:35:50 +08:00
|
|
|
//--
|
2014-11-18 02:06:21 +08:00
|
|
|
CMICmdCmdBreakCondition::~CMICmdCmdBreakCondition(void)
|
2014-06-25 00:35:50 +08:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
//++ ------------------------------------------------------------------------------------
|
2014-11-18 02:06:21 +08:00
|
|
|
// Details: The invoker requires this function. The parses the command line options
|
|
|
|
// arguments to extract values for each of those arguments.
|
|
|
|
// Type: Overridden.
|
|
|
|
// Args: None.
|
|
|
|
// Return: MIstatus::success - Functional succeeded.
|
|
|
|
// MIstatus::failure - Functional failed.
|
|
|
|
// Throws: None.
|
2014-06-25 00:35:50 +08:00
|
|
|
//--
|
2014-11-18 02:06:21 +08:00
|
|
|
bool
|
|
|
|
CMICmdCmdBreakCondition::ParseArgs(void)
|
2014-06-25 00:35:50 +08:00
|
|
|
{
|
2014-11-18 02:06:21 +08:00
|
|
|
bool bOk = m_setCmdArgs.Add(
|
|
|
|
*(new CMICmdArgValOptionLong(m_constStrArgNamedThreadGrp, false, false, CMICmdArgValListBase::eArgValType_ThreadGrp, 1)));
|
|
|
|
bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValNumber(m_constStrArgNamedNumber, true, true)));
|
|
|
|
bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValString(m_constStrArgNamedExpr, true, true, true, true)));
|
|
|
|
bOk = bOk &&
|
|
|
|
m_setCmdArgs.Add(*(new CMICmdArgValListOfN(m_constStrArgNamedExprNoQuotes, true, false,
|
|
|
|
CMICmdArgValListBase::eArgValType_StringQuotedNumber)));
|
|
|
|
return (bOk && ParseValidateCmdOptions());
|
2014-06-25 00:35:50 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
//++ ------------------------------------------------------------------------------------
|
2014-11-18 02:06:21 +08:00
|
|
|
// Details: The invoker requires this function. The command does work in this function.
|
|
|
|
// The command is likely to communicate with the LLDB SBDebugger in here.
|
|
|
|
// Type: Overridden.
|
|
|
|
// Args: None.
|
|
|
|
// Return: MIstatus::success - Functional succeeded.
|
|
|
|
// MIstatus::failure - Functional failed.
|
|
|
|
// Throws: None.
|
2014-06-25 00:35:50 +08:00
|
|
|
//--
|
2014-11-18 02:06:21 +08:00
|
|
|
bool
|
|
|
|
CMICmdCmdBreakCondition::Execute(void)
|
2014-06-25 00:35:50 +08:00
|
|
|
{
|
2014-11-18 02:06:21 +08:00
|
|
|
CMICMDBASE_GETOPTION(pArgNumber, Number, m_constStrArgNamedNumber);
|
|
|
|
CMICMDBASE_GETOPTION(pArgExpr, String, m_constStrArgNamedExpr);
|
|
|
|
|
|
|
|
m_nBrkPtId = pArgNumber->GetValue();
|
|
|
|
m_strBrkPtExpr = pArgExpr->GetValue();
|
|
|
|
m_strBrkPtExpr += GetRestOfExpressionNotSurroundedInQuotes();
|
|
|
|
|
|
|
|
CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
|
2015-02-03 18:05:54 +08:00
|
|
|
lldb::SBBreakpoint brkPt = rSessionInfo.GetTarget().FindBreakpointByID(static_cast<lldb::break_id_t>(m_nBrkPtId));
|
2014-11-18 02:06:21 +08:00
|
|
|
if (brkPt.IsValid())
|
|
|
|
{
|
|
|
|
brkPt.SetCondition(m_strBrkPtExpr.c_str());
|
|
|
|
|
|
|
|
CMICmnLLDBDebugSessionInfo::SBrkPtInfo sBrkPtInfo;
|
|
|
|
if (!rSessionInfo.RecordBrkPtInfoGet(m_nBrkPtId, sBrkPtInfo))
|
|
|
|
{
|
|
|
|
SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_BRKPT_INFO_OBJ_NOT_FOUND), m_cmdData.strMiCmd.c_str(), m_nBrkPtId));
|
|
|
|
return MIstatus::failure;
|
|
|
|
}
|
|
|
|
sBrkPtInfo.m_strCondition = m_strBrkPtExpr;
|
|
|
|
rSessionInfo.RecordBrkPtInfo(m_nBrkPtId, sBrkPtInfo);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
const CMIUtilString strBrkPtId(CMIUtilString::Format("%d", m_nBrkPtId));
|
|
|
|
SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_BRKPT_INVALID), m_cmdData.strMiCmd.c_str(), strBrkPtId.c_str()));
|
|
|
|
return MIstatus::failure;
|
|
|
|
}
|
|
|
|
|
|
|
|
return MIstatus::success;
|
2014-06-25 00:35:50 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
//++ ------------------------------------------------------------------------------------
|
2014-11-18 02:06:21 +08:00
|
|
|
// Details: The invoker requires this function. The command prepares a MI Record Result
|
|
|
|
// for the work carried out in the Execute().
|
|
|
|
// Type: Overridden.
|
|
|
|
// Args: None.
|
|
|
|
// Return: MIstatus::success - Functional succeeded.
|
|
|
|
// MIstatus::failure - Functional failed.
|
|
|
|
// Throws: None.
|
2014-06-25 00:35:50 +08:00
|
|
|
//--
|
2014-11-18 02:06:21 +08:00
|
|
|
bool
|
|
|
|
CMICmdCmdBreakCondition::Acknowledge(void)
|
2014-06-25 00:35:50 +08:00
|
|
|
{
|
2014-11-18 02:06:21 +08:00
|
|
|
const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done);
|
|
|
|
m_miResultRecord = miRecordResult;
|
2014-06-25 00:35:50 +08:00
|
|
|
|
2014-11-18 02:06:21 +08:00
|
|
|
return MIstatus::success;
|
2014-06-25 00:35:50 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
//++ ------------------------------------------------------------------------------------
|
2014-11-18 02:06:21 +08:00
|
|
|
// Details: Required by the CMICmdFactory when registering *this command. The factory
|
|
|
|
// calls this function to create an instance of *this command.
|
|
|
|
// Type: Static method.
|
|
|
|
// Args: None.
|
|
|
|
// Return: CMICmdBase * - Pointer to a new command.
|
|
|
|
// Throws: None.
|
2014-06-25 00:35:50 +08:00
|
|
|
//--
|
2014-11-18 02:06:21 +08:00
|
|
|
CMICmdBase *
|
|
|
|
CMICmdCmdBreakCondition::CreateSelf(void)
|
2014-06-25 00:35:50 +08:00
|
|
|
{
|
2014-11-18 02:06:21 +08:00
|
|
|
return new CMICmdCmdBreakCondition();
|
2014-06-25 00:35:50 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
//++ ------------------------------------------------------------------------------------
|
2014-11-18 02:06:21 +08:00
|
|
|
// Details: A breakpoint expression can be passed to *this command as:
|
|
|
|
// a single string i.e. '2' -> ok.
|
|
|
|
// a quoted string i.e. "a > 100" -> ok
|
|
|
|
// a non quoted string i.e. 'a > 100' -> not ok
|
|
|
|
// CMICmdArgValString only extracts the first space seperated string, the "a".
|
|
|
|
// This function using the optional argument type CMICmdArgValListOfN collects
|
|
|
|
// the rest of the expression so that is may be added to the 'a' part to form a
|
|
|
|
// complete expression string i.e. "a > 100".
|
|
|
|
// If the expression value was guaranteed to be surrounded by quotes them this
|
|
|
|
// function would not be necessary.
|
|
|
|
// Type: Method.
|
|
|
|
// Args: None.
|
|
|
|
// Return: CMIUtilString - Rest of the breakpoint expression.
|
|
|
|
// Throws: None.
|
2014-06-25 00:35:50 +08:00
|
|
|
//--
|
2014-11-18 02:06:21 +08:00
|
|
|
CMIUtilString
|
|
|
|
CMICmdCmdBreakCondition::GetRestOfExpressionNotSurroundedInQuotes(void)
|
2014-06-25 00:35:50 +08:00
|
|
|
{
|
2014-11-18 02:06:21 +08:00
|
|
|
CMIUtilString strExpression;
|
|
|
|
|
|
|
|
CMICmdArgValListOfN *pArgExprNoQuotes = CMICmdBase::GetOption<CMICmdArgValListOfN>(m_constStrArgNamedExprNoQuotes);
|
|
|
|
if (pArgExprNoQuotes != nullptr)
|
|
|
|
{
|
|
|
|
CMIUtilString strExpression;
|
|
|
|
const CMICmdArgValListBase::VecArgObjPtr_t &rVecExprParts(pArgExprNoQuotes->GetExpectedOptions());
|
|
|
|
if (!rVecExprParts.empty())
|
|
|
|
{
|
|
|
|
CMICmdArgValListBase::VecArgObjPtr_t::const_iterator it = rVecExprParts.begin();
|
|
|
|
while (it != rVecExprParts.end())
|
|
|
|
{
|
|
|
|
const CMICmdArgValString *pPartExpr = static_cast<CMICmdArgValString *>(*it);
|
|
|
|
const CMIUtilString &rPartExpr = pPartExpr->GetValue();
|
|
|
|
strExpression += " ";
|
|
|
|
strExpression += rPartExpr;
|
|
|
|
|
|
|
|
// Next
|
|
|
|
++it;
|
|
|
|
}
|
|
|
|
strExpression = strExpression.Trim();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return strExpression;
|
2014-06-25 00:35:50 +08:00
|
|
|
}
|