Files
clang-p2996/lldb/tools/lldb-mi/MICmdCmdVar.cpp
Sean Callanan 579e70c9b0 Add a DiagnosticManager replace error streams in the expression parser.
We want to do a better job presenting errors that occur when evaluating
expressions. Key to this effort is getting away from a model where all
errors are spat out onto a stream where the client has to take or leave
all of them.

To this end, this patch adds a new class, DiagnosticManager, which
contains errors produced by the compiler or by LLDB as an expression
is created. The DiagnosticManager can dump itself to a log as well as
to a string. Clients will (in the future) be able to filter out the
errors they're interested in by ID or present subsets of these errors
to the user.

This patch is not intended to change the *users* of errors - only to
thread DiagnosticManagers to all the places where streams are used. I
also attempt to standardize our use of errors a bit, removing trailing
newlines and making clients omit 'error:', 'warning:' etc. and instead
pass the Severity flag.

The patch is testsuite-neutral, with modifications to one part of the
MI tests because it relied on "error: error:" being erroneously
printed. This patch fixes the MI variable handling and the testcase.

<rdar://problem/22864976>

llvm-svn: 263859
2016-03-19 00:03:59 +00:00

1505 lines
57 KiB
C++

//===-- MICmdCmdVar.cpp -----------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// Overview: CMICmdCmdVarCreate implementation.
// CMICmdCmdVarUpdate implementation.
// CMICmdCmdVarDelete implementation.
// CMICmdCmdVarAssign implementation.
// CMICmdCmdVarSetFormat implementation.
// CMICmdCmdVarListChildren implementation.
// CMICmdCmdVarEvaluateExpression implementation.
// CMICmdCmdVarInfoPathExpression implementation.
// CMICmdCmdVarShowAttributes implementation.
// Third Party Headers:
#include "lldb/API/SBStream.h"
#include "lldb/API/SBType.h"
#include "lldb/API/SBThread.h"
// In-house headers:
#include "MICmdCmdVar.h"
#include "MICmnMIResultRecord.h"
#include "MICmnMIValueConst.h"
#include "MICmnLLDBDebugger.h"
#include "MICmnLLDBDebugSessionInfo.h"
#include "MICmdArgValNumber.h"
#include "MICmdArgValString.h"
#include "MICmdArgValThreadGrp.h"
#include "MICmdArgValOptionLong.h"
#include "MICmdArgValOptionShort.h"
#include "MICmdArgValPrintValues.h"
#include "MICmdArgValListOfN.h"
#include "MICmnLLDBProxySBValue.h"
#include "MICmnLLDBUtilSBValue.h"
//++ ------------------------------------------------------------------------------------
// Details: CMICmdCmdVarCreate constructor.
// Type: Method.
// Args: None.
// Return: None.
// Throws: None.
//--
CMICmdCmdVarCreate::CMICmdCmdVarCreate()
: m_nChildren(0)
, m_nThreadId(0)
, m_strType("??")
, m_bValid(false)
, m_strValue("??")
, m_constStrArgName("name")
, m_constStrArgFrameAddr("frame-addr")
, m_constStrArgExpression("expression")
{
// Command factory matches this name with that received from the stdin stream
m_strMiCmd = "var-create";
// Required by the CMICmdFactory when registering *this command
m_pSelfCreatorFn = &CMICmdCmdVarCreate::CreateSelf;
}
//++ ------------------------------------------------------------------------------------
// Details: CMICmdCmdVarCreate destructor.
// Type: Overrideable.
// Args: None.
// Return: None.
// Throws: None.
//--
CMICmdCmdVarCreate::~CMICmdCmdVarCreate()
{
}
//++ ------------------------------------------------------------------------------------
// 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.
//--
bool
CMICmdCmdVarCreate::ParseArgs()
{
m_setCmdArgs.Add(new CMICmdArgValString(m_constStrArgName, false, true));
m_setCmdArgs.Add(new CMICmdArgValString(m_constStrArgFrameAddr, false, true));
m_setCmdArgs.Add(new CMICmdArgValString(m_constStrArgExpression, true, true, true, true));
return ParseValidateCmdOptions();
}
//++ ------------------------------------------------------------------------------------
// 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.
//--
bool
CMICmdCmdVarCreate::Execute()
{
CMICMDBASE_GETOPTION(pArgThread, OptionLong, m_constStrArgThread);
CMICMDBASE_GETOPTION(pArgFrame, OptionLong, m_constStrArgFrame);
CMICMDBASE_GETOPTION(pArgName, String, m_constStrArgName);
CMICMDBASE_GETOPTION(pArgFrameAddr, String, m_constStrArgFrameAddr);
CMICMDBASE_GETOPTION(pArgExpression, String, m_constStrArgExpression);
// Retrieve the --thread option's thread ID (only 1)
MIuint64 nThreadId = UINT64_MAX;
if (pArgThread->GetFound() && !pArgThread->GetExpectedOption<CMICmdArgValNumber, MIuint64>(nThreadId))
{
SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_OPTION_NOT_FOUND), m_cmdData.strMiCmd.c_str(), m_constStrArgThread.c_str()));
return MIstatus::failure;
}
// Retrieve the --frame option's number
MIuint64 nFrame = UINT64_MAX;
if (pArgThread->GetFound() && !pArgFrame->GetExpectedOption<CMICmdArgValNumber, MIuint64>(nFrame))
{
SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_OPTION_NOT_FOUND), m_cmdData.strMiCmd.c_str(), m_constStrArgFrame.c_str()));
return MIstatus::failure;
}
const CMICmdArgValOptionLong::VecArgObjPtr_t &rVecFrameId(pArgFrame->GetExpectedOptions());
CMICmdArgValOptionLong::VecArgObjPtr_t::const_iterator it2 = rVecFrameId.begin();
if (it2 != rVecFrameId.end())
{
const CMICmdArgValNumber *pOption = static_cast<CMICmdArgValNumber *>(*it2);
nFrame = pOption->GetValue();
}
m_strVarName = "<unnamedvariable>";
if (pArgName->GetFound())
{
const CMIUtilString &rArg = pArgName->GetValue();
const bool bAutoName = (rArg == "-");
if (bAutoName)
{
m_strVarName = CMIUtilString::Format("var%u", CMICmnLLDBDebugSessionInfoVarObj::VarObjIdGet());
CMICmnLLDBDebugSessionInfoVarObj::VarObjIdInc();
}
else
m_strVarName = rArg;
}
bool bCurrentFrame = false;
if (pArgFrameAddr->GetFound())
{
const CMIUtilString &rStrFrameAddr(pArgFrameAddr->GetValue());
bCurrentFrame = CMIUtilString::Compare(rStrFrameAddr, "*");
if (!bCurrentFrame && (nFrame == UINT64_MAX))
{
//FIXME: *addr isn't implemented. Exit with error if --thread isn't specified.
SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_OPTION_NOT_FOUND), m_cmdData.strMiCmd.c_str(), m_constStrArgFrame.c_str()));
return MIstatus::failure;
}
}
const CMIUtilString &rStrExpression(pArgExpression->GetValue());
m_strExpression = rStrExpression;
CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
lldb::SBProcess sbProcess = rSessionInfo.GetProcess();
lldb::SBThread thread = (nThreadId != UINT64_MAX) ? sbProcess.GetThreadByIndexID(nThreadId) : sbProcess.GetSelectedThread();
m_nThreadId = thread.GetIndexID();
lldb::SBFrame frame = bCurrentFrame ? thread.GetSelectedFrame() : thread.GetFrameAtIndex(nFrame);
lldb::SBValue value;
if (rStrExpression[0] == '$')
{
const CMIUtilString rStrRegister(rStrExpression.substr(1));
value = frame.FindRegister(rStrRegister.c_str());
}
else
{
const bool bArgs = true;
const bool bLocals = true;
const bool bStatics = true;
const bool bInScopeOnly = false;
const lldb::SBValueList valueList = frame.GetVariables(bArgs, bLocals, bStatics, bInScopeOnly);
value = valueList.GetFirstValueByName(rStrExpression.c_str());
}
if (!value.IsValid())
value = frame.EvaluateExpression(rStrExpression.c_str());
if (value.IsValid() && value.GetError().Success())
{
CompleteSBValue(value);
m_bValid = true;
m_nChildren = value.GetNumChildren();
m_strType = CMICmnLLDBUtilSBValue(value).GetTypeNameDisplay();
// This gets added to CMICmnLLDBDebugSessionInfoVarObj static container of varObjs
CMICmnLLDBDebugSessionInfoVarObj varObj(rStrExpression, m_strVarName, value);
m_strValue = varObj.GetValueFormatted();
}
else
{
m_strValue = value.GetError().GetCString();
}
return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// 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.
//--
bool
CMICmdCmdVarCreate::Acknowledge()
{
if (m_bValid)
{
// MI print "%s^done,name=\"%s\",numchild=\"%d\",value=\"%s\",type=\"%s\",thread-id=\"%llu\",has_more=\"%u\""
const CMICmnMIValueConst miValueConst(m_strVarName);
CMICmnMIValueResult miValueResultAll("name", miValueConst);
const CMIUtilString strNumChild(CMIUtilString::Format("%d", m_nChildren));
const CMICmnMIValueConst miValueConst2(strNumChild);
miValueResultAll.Add("numchild", miValueConst2);
const CMICmnMIValueConst miValueConst3(m_strValue);
miValueResultAll.Add("value", miValueConst3);
const CMICmnMIValueConst miValueConst4(m_strType);
miValueResultAll.Add("type", miValueConst4);
const CMIUtilString strThreadId(CMIUtilString::Format("%llu", m_nThreadId));
const CMICmnMIValueConst miValueConst5(strThreadId);
miValueResultAll.Add("thread-id", miValueConst5);
const CMICmnMIValueConst miValueConst6("0");
miValueResultAll.Add("has_more", miValueConst6);
const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResultAll);
m_miResultRecord = miRecordResult;
return MIstatus::success;
}
CMIUtilString strErrMsg(m_strValue);
if (m_strValue.empty())
strErrMsg = CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_VARIABLE_CREATION_FAILED), m_strExpression.c_str());
const CMICmnMIValueConst miValueConst(strErrMsg.Escape(true /* vbEscapeQuotes */));
CMICmnMIValueResult miValueResult("msg", miValueConst);
const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult);
m_miResultRecord = miRecordResult;
return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// 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.
//--
CMICmdBase *
CMICmdCmdVarCreate::CreateSelf()
{
return new CMICmdCmdVarCreate();
}
//++ ------------------------------------------------------------------------------------
// Details: Complete SBValue object and its children to get SBValue::GetValueDidChange
// work.
// Type: Method.
// Args: vrwValue - (R) Value to update.
// Return: MIstatus::success - Functional succeeded.
// MIstatus::failure - Functional failed.
// Throws: None.
//--
void
CMICmdCmdVarCreate::CompleteSBValue(lldb::SBValue &vrwValue)
{
// Force a value to update
vrwValue.GetValueDidChange();
// And update its children
lldb::SBType valueType = vrwValue.GetType();
if (!valueType.IsPointerType() && !valueType.IsReferenceType())
{
const MIuint nChildren = vrwValue.GetNumChildren();
for (MIuint i = 0; i < nChildren; ++i)
{
lldb::SBValue member = vrwValue.GetChildAtIndex(i);
if (member.IsValid())
CompleteSBValue(member);
}
}
}
//---------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------
//++ ------------------------------------------------------------------------------------
// Details: CMICmdCmdVarUpdate constructor.
// Type: Method.
// Args: None.
// Return: None.
// Throws: None.
//--
CMICmdCmdVarUpdate::CMICmdCmdVarUpdate()
: m_constStrArgPrintValues("print-values")
, m_constStrArgName("name")
, m_bValueChanged(false)
, m_miValueList(true)
{
// Command factory matches this name with that received from the stdin stream
m_strMiCmd = "var-update";
// Required by the CMICmdFactory when registering *this command
m_pSelfCreatorFn = &CMICmdCmdVarUpdate::CreateSelf;
}
//++ ------------------------------------------------------------------------------------
// Details: CMICmdCmdVarUpdate destructor.
// Type: Overrideable.
// Args: None.
// Return: None.
// Throws: None.
//--
CMICmdCmdVarUpdate::~CMICmdCmdVarUpdate()
{
}
//++ ------------------------------------------------------------------------------------
// 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.
//--
bool
CMICmdCmdVarUpdate::ParseArgs()
{
m_setCmdArgs.Add(new CMICmdArgValPrintValues(m_constStrArgPrintValues, false, true));
m_setCmdArgs.Add(new CMICmdArgValString(m_constStrArgName, true, true));
return ParseValidateCmdOptions();
}
//++ ------------------------------------------------------------------------------------
// 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.
//--
bool
CMICmdCmdVarUpdate::Execute()
{
CMICMDBASE_GETOPTION(pArgPrintValues, PrintValues, m_constStrArgPrintValues);
CMICMDBASE_GETOPTION(pArgName, String, m_constStrArgName);
CMICmnLLDBDebugSessionInfo::VariableInfoFormat_e eVarInfoFormat = CMICmnLLDBDebugSessionInfo::eVariableInfoFormat_NoValues;
if (pArgPrintValues->GetFound())
eVarInfoFormat = static_cast<CMICmnLLDBDebugSessionInfo::VariableInfoFormat_e>(pArgPrintValues->GetValue());
const CMIUtilString &rVarObjName(pArgName->GetValue());
CMICmnLLDBDebugSessionInfoVarObj varObj;
if (!CMICmnLLDBDebugSessionInfoVarObj::VarObjGet(rVarObjName, varObj))
{
SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_VARIABLE_DOESNOTEXIST), m_cmdData.strMiCmd.c_str(), rVarObjName.c_str()));
return MIstatus::failure;
}
lldb::SBValue &rValue = varObj.GetValue();
if (!ExamineSBValueForChange(rValue, m_bValueChanged))
return MIstatus::failure;
if (m_bValueChanged)
{
varObj.UpdateValue();
const bool bPrintValue((eVarInfoFormat == CMICmnLLDBDebugSessionInfo::eVariableInfoFormat_AllValues) ||
(eVarInfoFormat == CMICmnLLDBDebugSessionInfo::eVariableInfoFormat_SimpleValues && rValue.GetNumChildren() == 0));
const CMIUtilString strValue(bPrintValue ? varObj.GetValueFormatted() : "");
const CMIUtilString strInScope(rValue.IsInScope() ? "true" : "false");
MIFormResponse(rVarObjName, bPrintValue ? strValue.c_str() : nullptr, strInScope);
}
return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// 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.
//--
bool
CMICmdCmdVarUpdate::Acknowledge()
{
if (m_bValueChanged)
{
// MI print "%s^done,changelist=[{name=\"%s\",value=\"%s\",in_scope=\"%s\",type_changed=\"false\",has_more=\"0\"}]"
CMICmnMIValueResult miValueResult("changelist", m_miValueList);
const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult);
m_miResultRecord = miRecordResult;
}
else
{
// MI print "%s^done,changelist=[]"
const CMICmnMIValueList miValueList(true);
CMICmnMIValueResult miValueResult6("changelist", miValueList);
const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult6);
m_miResultRecord = miRecordResult;
}
return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// 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.
//--
CMICmdBase *
CMICmdCmdVarUpdate::CreateSelf()
{
return new CMICmdCmdVarUpdate();
}
//++ ------------------------------------------------------------------------------------
// Details: Form the MI response for multiple variables.
// Type: Method.
// Args: vrStrVarName - (R) Session var object's name.
// vpValue - (R) Text version of the value held in the variable.
// vrStrScope - (R) In scope "yes" or "no".
// Return: None.
// Throws: None.
//--
void
CMICmdCmdVarUpdate::MIFormResponse(const CMIUtilString &vrStrVarName, const char *const vpValue, const CMIUtilString &vrStrScope)
{
// MI print "[{name=\"%s\",value=\"%s\",in_scope=\"%s\",type_changed=\"false\",has_more=\"0\"}]"
const CMICmnMIValueConst miValueConst(vrStrVarName);
const CMICmnMIValueResult miValueResult("name", miValueConst);
CMICmnMIValueTuple miValueTuple(miValueResult);
if (vpValue != nullptr)
{
const CMICmnMIValueConst miValueConst2(vpValue);
const CMICmnMIValueResult miValueResult2("value", miValueConst2);
miValueTuple.Add(miValueResult2);
}
const CMICmnMIValueConst miValueConst3(vrStrScope);
const CMICmnMIValueResult miValueResult3("in_scope", miValueConst3);
miValueTuple.Add(miValueResult3);
const CMICmnMIValueConst miValueConst4("false");
const CMICmnMIValueResult miValueResult4("type_changed", miValueConst4);
miValueTuple.Add(miValueResult4);
const CMICmnMIValueConst miValueConst5("0");
const CMICmnMIValueResult miValueResult5("has_more", miValueConst5);
miValueTuple.Add(miValueResult5);
m_miValueList.Add(miValueTuple);
}
//++ ------------------------------------------------------------------------------------
// Details: Determine if the var object was changed.
// Type: Method.
// Args: vrVarObj - (R) Session var object to examine.
// vrwbChanged - (W) True = The var object was changed,
// False = It was not changed.
// Return: MIstatus::success - Functional succeeded.
// MIstatus::failure - Functional failed.
// Throws: None.
//--
bool
CMICmdCmdVarUpdate::ExamineSBValueForChange(lldb::SBValue &vrwValue, bool &vrwbChanged)
{
if (vrwValue.GetValueDidChange())
{
vrwbChanged = true;
return MIstatus::success;
}
lldb::SBType valueType = vrwValue.GetType();
if (!valueType.IsPointerType() && !valueType.IsReferenceType())
{
const MIuint nChildren = vrwValue.GetNumChildren();
for (MIuint i = 0; i < nChildren; ++i)
{
lldb::SBValue member = vrwValue.GetChildAtIndex(i);
if (!member.IsValid())
continue;
if (member.GetValueDidChange())
{
vrwbChanged = true;
return MIstatus::success;
}
else if (ExamineSBValueForChange(member, vrwbChanged) && vrwbChanged)
// Handle composite types (i.e. struct or arrays)
return MIstatus::success;
}
}
vrwbChanged = false;
return MIstatus::success;
}
//---------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------
//++ ------------------------------------------------------------------------------------
// Details: CMICmdCmdVarDelete constructor.
// Type: Method.
// Args: None.
// Return: None.
// Throws: None.
//--
CMICmdCmdVarDelete::CMICmdCmdVarDelete()
: m_constStrArgName("name")
{
// Command factory matches this name with that received from the stdin stream
m_strMiCmd = "var-delete";
// Required by the CMICmdFactory when registering *this command
m_pSelfCreatorFn = &CMICmdCmdVarDelete::CreateSelf;
}
//++ ------------------------------------------------------------------------------------
// 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.
//--
bool
CMICmdCmdVarDelete::ParseArgs()
{
m_setCmdArgs.Add(new CMICmdArgValString(m_constStrArgName, true, true));
return ParseValidateCmdOptions();
}
//++ ------------------------------------------------------------------------------------
// Details: CMICmdCmdVarDelete destructor.
// Type: Overrideable.
// Args: None.
// Return: None.
// Throws: None.
//--
CMICmdCmdVarDelete::~CMICmdCmdVarDelete()
{
}
//++ ------------------------------------------------------------------------------------
// 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.
//--
bool
CMICmdCmdVarDelete::Execute()
{
CMICMDBASE_GETOPTION(pArgName, String, m_constStrArgName);
const CMIUtilString &rVarObjName(pArgName->GetValue());
CMICmnLLDBDebugSessionInfoVarObj::VarObjDelete(rVarObjName);
return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// 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.
//--
bool
CMICmdCmdVarDelete::Acknowledge()
{
const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done);
m_miResultRecord = miRecordResult;
return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// 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.
//--
CMICmdBase *
CMICmdCmdVarDelete::CreateSelf()
{
return new CMICmdCmdVarDelete();
}
//---------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------
//++ ------------------------------------------------------------------------------------
// Details: CMICmdCmdVarAssign constructor.
// Type: Method.
// Args: None.
// Return: None.
// Throws: None.
//--
CMICmdCmdVarAssign::CMICmdCmdVarAssign()
: m_bOk(true)
, m_constStrArgName("name")
, m_constStrArgExpression("expression")
{
// Command factory matches this name with that received from the stdin stream
m_strMiCmd = "var-assign";
// Required by the CMICmdFactory when registering *this command
m_pSelfCreatorFn = &CMICmdCmdVarAssign::CreateSelf;
}
//++ ------------------------------------------------------------------------------------
// Details: CMICmdCmdVarAssign destructor.
// Type: Overrideable.
// Args: None.
// Return: None.
// Throws: None.
//--
CMICmdCmdVarAssign::~CMICmdCmdVarAssign()
{
}
//++ ------------------------------------------------------------------------------------
// 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.
//--
bool
CMICmdCmdVarAssign::ParseArgs()
{
m_setCmdArgs.Add(new CMICmdArgValString(m_constStrArgName, true, true));
m_setCmdArgs.Add(new CMICmdArgValString(m_constStrArgExpression, true, true));
return ParseValidateCmdOptions();
}
//++ ------------------------------------------------------------------------------------
// 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.
//--
bool
CMICmdCmdVarAssign::Execute()
{
CMICMDBASE_GETOPTION(pArgName, String, m_constStrArgName);
CMICMDBASE_GETOPTION(pArgExpression, String, m_constStrArgExpression);
const CMIUtilString &rVarObjName(pArgName->GetValue());
const CMIUtilString &rExpression(pArgExpression->GetValue());
CMICmnLLDBDebugSessionInfoVarObj varObj;
if (!CMICmnLLDBDebugSessionInfoVarObj::VarObjGet(rVarObjName, varObj))
{
SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_VARIABLE_DOESNOTEXIST), m_cmdData.strMiCmd.c_str(), rVarObjName.c_str()));
return MIstatus::failure;
}
m_varObjName = rVarObjName;
CMIUtilString strExpression(rExpression.Trim());
strExpression = strExpression.Trim('"');
lldb::SBValue &rValue(const_cast<lldb::SBValue &>(varObj.GetValue()));
m_bOk = rValue.SetValueFromCString(strExpression.c_str());
if (m_bOk)
varObj.UpdateValue();
return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// 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.
//--
bool
CMICmdCmdVarAssign::Acknowledge()
{
if (m_bOk)
{
// MI print "%s^done,value=\"%s\""
CMICmnLLDBDebugSessionInfoVarObj varObj;
CMICmnLLDBDebugSessionInfoVarObj::VarObjGet(m_varObjName, varObj);
const CMICmnMIValueConst miValueConst(varObj.GetValueFormatted());
const CMICmnMIValueResult miValueResult("value", miValueConst);
const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult);
m_miResultRecord = miRecordResult;
return MIstatus::success;
}
const CMICmnMIValueConst miValueConst("expression could not be evaluated");
const CMICmnMIValueResult miValueResult("msg", miValueConst);
const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult);
m_miResultRecord = miRecordResult;
return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// 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.
//--
CMICmdBase *
CMICmdCmdVarAssign::CreateSelf()
{
return new CMICmdCmdVarAssign();
}
//---------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------
//++ ------------------------------------------------------------------------------------
// Details: CMICmdCmdVarSetFormat constructor.
// Type: Method.
// Args: None.
// Return: None.
// Throws: None.
//--
CMICmdCmdVarSetFormat::CMICmdCmdVarSetFormat()
: m_constStrArgName("name")
, m_constStrArgFormatSpec("format-spec")
{
// Command factory matches this name with that received from the stdin stream
m_strMiCmd = "var-set-format";
// Required by the CMICmdFactory when registering *this command
m_pSelfCreatorFn = &CMICmdCmdVarSetFormat::CreateSelf;
}
//++ ------------------------------------------------------------------------------------
// Details: CMICmdCmdVarSetFormat destructor.
// Type: Overrideable.
// Args: None.
// Return: None.
// Throws: None.
//--
CMICmdCmdVarSetFormat::~CMICmdCmdVarSetFormat()
{
}
//++ ------------------------------------------------------------------------------------
// 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.
//--
bool
CMICmdCmdVarSetFormat::ParseArgs()
{
m_setCmdArgs.Add(new CMICmdArgValString(m_constStrArgName, true, true));
m_setCmdArgs.Add(new CMICmdArgValString(m_constStrArgFormatSpec, true, true));
return ParseValidateCmdOptions();
}
//++ ------------------------------------------------------------------------------------
// 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.
//--
bool
CMICmdCmdVarSetFormat::Execute()
{
CMICMDBASE_GETOPTION(pArgName, String, m_constStrArgName);
CMICMDBASE_GETOPTION(pArgFormatSpec, String, m_constStrArgFormatSpec);
const CMIUtilString &rVarObjName(pArgName->GetValue());
const CMIUtilString &rExpression(pArgFormatSpec->GetValue());
CMICmnLLDBDebugSessionInfoVarObj varObj;
if (!CMICmnLLDBDebugSessionInfoVarObj::VarObjGet(rVarObjName, varObj))
{
SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_VARIABLE_DOESNOTEXIST), m_cmdData.strMiCmd.c_str(), rVarObjName.c_str()));
return MIstatus::failure;
}
if (!varObj.SetVarFormat(CMICmnLLDBDebugSessionInfoVarObj::GetVarFormatForString(rExpression)))
{
SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_VARIABLE_ENUM_INVALID), m_cmdData.strMiCmd.c_str(), rVarObjName.c_str(),
rExpression.c_str()));
return MIstatus::failure;
}
varObj.UpdateValue();
m_varObjName = rVarObjName;
return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// 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.
//--
bool
CMICmdCmdVarSetFormat::Acknowledge()
{
// MI print "%s^done,changelist=[{name=\"%s\",value=\"%s\",in_scope=\"%s\",type_changed=\"false\",has_more=\"0\"}]"
CMICmnLLDBDebugSessionInfoVarObj varObj;
CMICmnLLDBDebugSessionInfoVarObj::VarObjGet(m_varObjName, varObj);
const CMICmnMIValueConst miValueConst(m_varObjName);
const CMICmnMIValueResult miValueResult("name", miValueConst);
CMICmnMIValueTuple miValueTuple(miValueResult);
const CMICmnMIValueConst miValueConst2(varObj.GetValueFormatted());
const CMICmnMIValueResult miValueResult2("value", miValueConst2);
miValueTuple.Add(miValueResult2);
lldb::SBValue &rValue = const_cast<lldb::SBValue &>(varObj.GetValue());
const CMICmnMIValueConst miValueConst3(rValue.IsInScope() ? "true" : "false");
const CMICmnMIValueResult miValueResult3("in_scope", miValueConst3);
miValueTuple.Add(miValueResult3);
const CMICmnMIValueConst miValueConst4("false");
const CMICmnMIValueResult miValueResult4("type_changed", miValueConst4);
miValueTuple.Add(miValueResult4);
const CMICmnMIValueConst miValueConst5("0");
const CMICmnMIValueResult miValueResult5("type_changed", miValueConst5);
miValueTuple.Add(miValueResult5);
const CMICmnMIValueList miValueList(miValueTuple);
const CMICmnMIValueResult miValueResult6("changelist", miValueList);
const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult6);
m_miResultRecord = miRecordResult;
return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// 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.
//--
CMICmdBase *
CMICmdCmdVarSetFormat::CreateSelf()
{
return new CMICmdCmdVarSetFormat();
}
//---------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------
//++ ------------------------------------------------------------------------------------
// Details: CMICmdCmdVarListChildren constructor.
// Type: Method.
// Args: None.
// Return: None.
// Throws: None.
//--
CMICmdCmdVarListChildren::CMICmdCmdVarListChildren()
: m_constStrArgPrintValues("print-values")
, m_constStrArgName("name")
, m_constStrArgFrom("from")
, m_constStrArgTo("to")
, m_bValueValid(false)
, m_nChildren(0)
, m_miValueList(true)
, m_bHasMore(false)
{
// Command factory matches this name with that received from the stdin stream
m_strMiCmd = "var-list-children";
// Required by the CMICmdFactory when registering *this command
m_pSelfCreatorFn = &CMICmdCmdVarListChildren::CreateSelf;
}
//++ ------------------------------------------------------------------------------------
// Details: CMICmdCmdVarListChildren destructor.
// Type: Overrideable.
// Args: None.
// Return: None.
// Throws: None.
//--
CMICmdCmdVarListChildren::~CMICmdCmdVarListChildren()
{
}
//++ ------------------------------------------------------------------------------------
// 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.
//--
bool
CMICmdCmdVarListChildren::ParseArgs()
{
m_setCmdArgs.Add(new CMICmdArgValPrintValues(m_constStrArgPrintValues, false, true));
m_setCmdArgs.Add(new CMICmdArgValString(m_constStrArgName, true, true, true));
m_setCmdArgs.Add(new CMICmdArgValNumber(m_constStrArgFrom, false, true));
m_setCmdArgs.Add(new CMICmdArgValNumber(m_constStrArgTo, false, true));
return ParseValidateCmdOptions();
}
//++ ------------------------------------------------------------------------------------
// 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.
//--
bool
CMICmdCmdVarListChildren::Execute()
{
CMICMDBASE_GETOPTION(pArgPrintValues, PrintValues, m_constStrArgPrintValues);
CMICMDBASE_GETOPTION(pArgName, String, m_constStrArgName);
CMICMDBASE_GETOPTION(pArgFrom, Number, m_constStrArgFrom);
CMICMDBASE_GETOPTION(pArgTo, Number, m_constStrArgTo);
CMICmnLLDBDebugSessionInfo::VariableInfoFormat_e eVarInfoFormat = CMICmnLLDBDebugSessionInfo::eVariableInfoFormat_NoValues;
if (pArgPrintValues->GetFound())
eVarInfoFormat = static_cast<CMICmnLLDBDebugSessionInfo::VariableInfoFormat_e>(pArgPrintValues->GetValue());
const CMIUtilString &rVarObjName(pArgName->GetValue());
CMICmnLLDBDebugSessionInfoVarObj varObj;
if (!CMICmnLLDBDebugSessionInfoVarObj::VarObjGet(rVarObjName, varObj))
{
SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_VARIABLE_DOESNOTEXIST), m_cmdData.strMiCmd.c_str(), rVarObjName.c_str()));
return MIstatus::failure;
}
MIuint nFrom = 0;
MIuint nTo = UINT32_MAX;
if (pArgFrom->GetFound() && pArgTo->GetFound())
{
nFrom = pArgFrom->GetValue();
nTo = pArgTo->GetValue();
}
else if (pArgFrom->GetFound() || pArgTo->GetFound())
{
// Only from or to was specified but both are required
SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_VARIABLE_CHILD_RANGE_INVALID), m_cmdData.strMiCmd.c_str()));
return MIstatus::failure;
}
lldb::SBValue &rValue = const_cast<lldb::SBValue &>(varObj.GetValue());
m_bValueValid = rValue.IsValid();
if (!m_bValueValid)
return MIstatus::success;
const MIuint nChildren = rValue.GetNumChildren();
m_bHasMore = nTo < nChildren;
nTo = std::min(nTo, nChildren);
m_nChildren = nFrom < nTo ? nTo - nFrom : 0;
for (MIuint i = nFrom; i < nTo; i++)
{
lldb::SBValue member = rValue.GetChildAtIndex(i);
const CMICmnLLDBUtilSBValue utilValue(member);
const CMIUtilString strExp = utilValue.GetName();
const CMIUtilString name(strExp.empty() ?
CMIUtilString::Format("%s.$%u", rVarObjName.c_str(), i) :
CMIUtilString::Format("%s.%s", rVarObjName.c_str(), strExp.c_str()));
const MIuint nChildren = member.GetNumChildren();
const CMIUtilString strThreadId(CMIUtilString::Format("%u", member.GetThread().GetIndexID()));
// Varobj gets added to CMICmnLLDBDebugSessionInfoVarObj static container of varObjs
CMICmnLLDBDebugSessionInfoVarObj var(strExp, name, member, rVarObjName);
// MI print "child={name=\"%s\",exp=\"%s\",numchild=\"%d\",value=\"%s\",type=\"%s\",thread-id=\"%u\",has_more=\"%u\"}"
const CMICmnMIValueConst miValueConst(name);
const CMICmnMIValueResult miValueResult("name", miValueConst);
CMICmnMIValueTuple miValueTuple(miValueResult);
const CMICmnMIValueConst miValueConst2(strExp);
const CMICmnMIValueResult miValueResult2("exp", miValueConst2);
miValueTuple.Add(miValueResult2);
const CMIUtilString strNumChild(CMIUtilString::Format("%u", nChildren));
const CMICmnMIValueConst miValueConst3(strNumChild);
const CMICmnMIValueResult miValueResult3("numchild", miValueConst3);
miValueTuple.Add(miValueResult3);
const CMICmnMIValueConst miValueConst5(utilValue.GetTypeNameDisplay());
const CMICmnMIValueResult miValueResult5("type", miValueConst5);
miValueTuple.Add(miValueResult5);
const CMICmnMIValueConst miValueConst6(strThreadId);
const CMICmnMIValueResult miValueResult6("thread-id", miValueConst6);
miValueTuple.Add(miValueResult6);
// nChildren == 0 is used to check for simple values
if (eVarInfoFormat == CMICmnLLDBDebugSessionInfo::eVariableInfoFormat_AllValues ||
(eVarInfoFormat == CMICmnLLDBDebugSessionInfo::eVariableInfoFormat_SimpleValues && nChildren == 0))
{
const CMIUtilString strValue(
CMICmnLLDBDebugSessionInfoVarObj::GetValueStringFormatted(member, CMICmnLLDBDebugSessionInfoVarObj::eVarFormat_Natural));
const CMICmnMIValueConst miValueConst7(strValue);
const CMICmnMIValueResult miValueResult7("value", miValueConst7);
miValueTuple.Add(miValueResult7);
}
const CMICmnMIValueConst miValueConst8("0");
const CMICmnMIValueResult miValueResult8("has_more", miValueConst8);
miValueTuple.Add(miValueResult8);
const CMICmnMIValueResult miValueResult9("child", miValueTuple);
m_miValueList.Add(miValueResult9);
}
return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// 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.
//--
bool
CMICmdCmdVarListChildren::Acknowledge()
{
if (m_bValueValid)
{
// MI print "%s^done,numchild=\"%u\",children=[%s],has_more=\"%d\""
const CMIUtilString strNumChild(CMIUtilString::Format("%u", m_nChildren));
const CMICmnMIValueConst miValueConst(strNumChild);
CMICmnMIValueResult miValueResult("numchild", miValueConst);
if (m_nChildren != 0)
miValueResult.Add("children", m_miValueList);
const CMIUtilString strHasMore(m_bHasMore ? "1" : "0");
const CMICmnMIValueConst miValueConst2(strHasMore);
miValueResult.Add("has_more", miValueConst2);
const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult);
m_miResultRecord = miRecordResult;
return MIstatus::success;
}
// MI print "%s^error,msg=\"variable invalid\""
const CMICmnMIValueConst miValueConst("variable invalid");
const CMICmnMIValueResult miValueResult("msg", miValueConst);
const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult);
m_miResultRecord = miRecordResult;
return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// 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.
//--
CMICmdBase *
CMICmdCmdVarListChildren::CreateSelf()
{
return new CMICmdCmdVarListChildren();
}
//---------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------
//++ ------------------------------------------------------------------------------------
// Details: CMICmdCmdVarEvaluateExpression constructor.
// Type: Method.
// Args: None.
// Return: None.
// Throws: None.
//--
CMICmdCmdVarEvaluateExpression::CMICmdCmdVarEvaluateExpression()
: m_bValueValid(true)
, m_constStrArgFormatSpec("-f")
, m_constStrArgName("name")
{
// Command factory matches this name with that received from the stdin stream
m_strMiCmd = "var-evaluate-expression";
// Required by the CMICmdFactory when registering *this command
m_pSelfCreatorFn = &CMICmdCmdVarEvaluateExpression::CreateSelf;
}
//++ ------------------------------------------------------------------------------------
// Details: CMICmdCmdVarEvaluateExpression destructor.
// Type: Overrideable.
// Args: None.
// Return: None.
// Throws: None.
//--
CMICmdCmdVarEvaluateExpression::~CMICmdCmdVarEvaluateExpression()
{
}
//++ ------------------------------------------------------------------------------------
// 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.
//--
bool
CMICmdCmdVarEvaluateExpression::ParseArgs()
{
m_setCmdArgs.Add(
new CMICmdArgValOptionShort(m_constStrArgFormatSpec, false, false, CMICmdArgValListBase::eArgValType_String, 1));
m_setCmdArgs.Add(new CMICmdArgValString(m_constStrArgName, true, true));
return ParseValidateCmdOptions();
}
//++ ------------------------------------------------------------------------------------
// 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.
//--
bool
CMICmdCmdVarEvaluateExpression::Execute()
{
CMICMDBASE_GETOPTION(pArgName, String, m_constStrArgName);
const CMIUtilString &rVarObjName(pArgName->GetValue());
CMICmnLLDBDebugSessionInfoVarObj varObj;
if (!CMICmnLLDBDebugSessionInfoVarObj::VarObjGet(rVarObjName, varObj))
{
SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_VARIABLE_DOESNOTEXIST), m_cmdData.strMiCmd.c_str(), rVarObjName.c_str()));
return MIstatus::failure;
}
lldb::SBValue &rValue = const_cast<lldb::SBValue &>(varObj.GetValue());
m_bValueValid = rValue.IsValid();
if (!m_bValueValid)
return MIstatus::success;
m_varObjName = rVarObjName;
varObj.UpdateValue();
return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// 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.
//--
bool
CMICmdCmdVarEvaluateExpression::Acknowledge()
{
if (m_bValueValid)
{
CMICmnLLDBDebugSessionInfoVarObj varObj;
CMICmnLLDBDebugSessionInfoVarObj::VarObjGet(m_varObjName, varObj);
const CMICmnMIValueConst miValueConst(varObj.GetValueFormatted());
const CMICmnMIValueResult miValueResult("value", miValueConst);
const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult);
m_miResultRecord = miRecordResult;
return MIstatus::success;
}
const CMICmnMIValueConst miValueConst("variable invalid");
const CMICmnMIValueResult miValueResult("msg", miValueConst);
const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult);
m_miResultRecord = miRecordResult;
return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// 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.
//--
CMICmdBase *
CMICmdCmdVarEvaluateExpression::CreateSelf()
{
return new CMICmdCmdVarEvaluateExpression();
}
//---------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------
//++ ------------------------------------------------------------------------------------
// Details: CMICmdCmdVarInfoPathExpression constructor.
// Type: Method.
// Args: None.
// Return: None.
// Throws: None.
//--
CMICmdCmdVarInfoPathExpression::CMICmdCmdVarInfoPathExpression()
: m_bValueValid(true)
, m_constStrArgName("name")
{
// Command factory matches this name with that received from the stdin stream
m_strMiCmd = "var-info-path-expression";
// Required by the CMICmdFactory when registering *this command
m_pSelfCreatorFn = &CMICmdCmdVarInfoPathExpression::CreateSelf;
}
//++ ------------------------------------------------------------------------------------
// Details: CMICmdCmdVarInfoPathExpression destructor.
// Type: Overrideable.
// Args: None.
// Return: None.
// Throws: None.
//--
CMICmdCmdVarInfoPathExpression::~CMICmdCmdVarInfoPathExpression()
{
}
//++ ------------------------------------------------------------------------------------
// 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.
//--
bool
CMICmdCmdVarInfoPathExpression::ParseArgs()
{
m_setCmdArgs.Add(new CMICmdArgValString(m_constStrArgName, true, true));
return ParseValidateCmdOptions();
}
//++ ------------------------------------------------------------------------------------
// 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.
//--
bool
CMICmdCmdVarInfoPathExpression::Execute()
{
CMICMDBASE_GETOPTION(pArgName, String, m_constStrArgName);
const CMIUtilString &rVarObjName(pArgName->GetValue());
CMICmnLLDBDebugSessionInfoVarObj varObj;
if (!CMICmnLLDBDebugSessionInfoVarObj::VarObjGet(rVarObjName, varObj))
{
SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_VARIABLE_DOESNOTEXIST), m_cmdData.strMiCmd.c_str(), rVarObjName.c_str()));
return MIstatus::failure;
}
lldb::SBValue &rValue = const_cast<lldb::SBValue &>(varObj.GetValue());
m_bValueValid = rValue.IsValid();
if (!m_bValueValid)
return MIstatus::success;
lldb::SBStream stream;
if (!rValue.GetExpressionPath(stream, true))
{
SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_VARIABLE_EXPRESSIONPATH), m_cmdData.strMiCmd.c_str(), rVarObjName.c_str()));
return MIstatus::failure;
}
const char *pPathExpression = stream.GetData();
if (pPathExpression == nullptr)
{
// Build expression from what we do know
m_strPathExpression = varObj.GetNameReal();
return MIstatus::success;
}
// Has LLDB returned a var signature of it's own
if (pPathExpression[0] != '$')
{
m_strPathExpression = pPathExpression;
return MIstatus::success;
}
// Build expression from what we do know
const CMIUtilString &rVarParentName(varObj.GetVarParentName());
if (rVarParentName.empty())
{
m_strPathExpression = varObj.GetNameReal();
}
else
{
CMICmnLLDBDebugSessionInfoVarObj varObjParent;
if (!CMICmnLLDBDebugSessionInfoVarObj::VarObjGet(rVarParentName, varObjParent))
{
SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_VARIABLE_DOESNOTEXIST), m_cmdData.strMiCmd.c_str(), rVarParentName.c_str()));
return MIstatus::failure;
}
m_strPathExpression = CMIUtilString::Format("%s.%s", varObjParent.GetNameReal().c_str(), varObj.GetNameReal().c_str());
}
return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// 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.
//--
bool
CMICmdCmdVarInfoPathExpression::Acknowledge()
{
if (m_bValueValid)
{
const CMICmnMIValueConst miValueConst(m_strPathExpression);
const CMICmnMIValueResult miValueResult("path_expr", miValueConst);
const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult);
m_miResultRecord = miRecordResult;
return MIstatus::success;
}
const CMICmnMIValueConst miValueConst("variable invalid");
const CMICmnMIValueResult miValueResult("msg", miValueConst);
const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult);
m_miResultRecord = miRecordResult;
return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// 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.
//--
CMICmdBase *
CMICmdCmdVarInfoPathExpression::CreateSelf()
{
return new CMICmdCmdVarInfoPathExpression();
}
//---------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------
//++ ------------------------------------------------------------------------------------
// Details: CMICmdCmdVarShowAttributes constructor.
// Type: Method.
// Args: None.
// Return: None.
// Throws: None.
//--
CMICmdCmdVarShowAttributes::CMICmdCmdVarShowAttributes()
: m_constStrArgName("name")
{
// Command factory matches this name with that received from the stdin stream
m_strMiCmd = "var-show-attributes";
// Required by the CMICmdFactory when registering *this command
m_pSelfCreatorFn = &CMICmdCmdVarShowAttributes::CreateSelf;
}
//++ ------------------------------------------------------------------------------------
// Details: CMICmdCmdVarShowAttributes destructor.
// Type: Overrideable.
// Args: None.
// Return: None.
// Throws: None.
//--
CMICmdCmdVarShowAttributes::~CMICmdCmdVarShowAttributes()
{
}
//++ ------------------------------------------------------------------------------------
// 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.
//--
bool
CMICmdCmdVarShowAttributes::ParseArgs()
{
m_setCmdArgs.Add(new CMICmdArgValString(m_constStrArgName, true, true));
return ParseValidateCmdOptions();
}
//++ ------------------------------------------------------------------------------------
// 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.
//--
bool
CMICmdCmdVarShowAttributes::Execute()
{
CMICMDBASE_GETOPTION(pArgName, String, m_constStrArgName);
const CMIUtilString &rVarObjName(pArgName->GetValue());
CMICmnLLDBDebugSessionInfoVarObj varObj;
if (!CMICmnLLDBDebugSessionInfoVarObj::VarObjGet(rVarObjName, varObj))
{
SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_VARIABLE_DOESNOTEXIST), m_cmdData.strMiCmd.c_str(), rVarObjName.c_str()));
return MIstatus::failure;
}
return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// 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.
//--
bool
CMICmdCmdVarShowAttributes::Acknowledge()
{
// MI output: "%s^done,status=\"editable\"]"
const CMICmnMIValueConst miValueConst("editable");
const CMICmnMIValueResult miValueResult("status", miValueConst);
const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult);
m_miResultRecord = miRecordResult;
return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// 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.
//--
CMICmdBase *
CMICmdCmdVarShowAttributes::CreateSelf()
{
return new CMICmdCmdVarShowAttributes();
}