| //===-- MICmdCmdVar.cpp -----------------------------------------*- C++ -*-===// |
| // |
| // The LLVM Compiler Infrastructure |
| // |
| // This file is distributed under the University of Illinois Open Source |
| // License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| //++ |
| // File: MICmdCmdVar.cpp |
| // |
| // Overview: CMICmdCmdVarCreate implementation. |
| // CMICmdCmdVarUpdate implementation. |
| // CMICmdCmdVarDelete implementation. |
| // CMICmdCmdVarAssign implementation. |
| // CMICmdCmdVarSetFormat implementation. |
| // CMICmdCmdVarListChildren implementation. |
| // CMICmdCmdVarEvaluateExpression implementation. |
| // CMICmdCmdVarInfoPathExpression implementation. |
| // CMICmdCmdVarShowAttributes implementation. |
| // |
| // Environment: Compilers: Visual C++ 12. |
| // gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1 |
| // Libraries: See MIReadmetxt. |
| // |
| // Copyright: None. |
| //-- |
| |
| // Third Party Headers: |
| #include <lldb/API/SBStream.h> |
| #include <lldb/API/SBThread.h> |
| |
| // In-house headers: |
| #include "MICmnConfig.h" |
| #include "MICmdCmdVar.h" |
| #include "MICmnMIResultRecord.h" |
| #include "MICmnMIValueConst.h" |
| #include "MICmnLLDBDebugger.h" |
| #include "MICmnLLDBDebugSessionInfo.h" |
| #include "MICmdArgContext.h" |
| #include "MICmdArgValNumber.h" |
| #include "MICmdArgValString.h" |
| #include "MICmdArgValThreadGrp.h" |
| #include "MICmdArgValOptionLong.h" |
| #include "MICmdArgValOptionShort.h" |
| #include "MICmdArgValListOfN.h" |
| #include "MICmnLLDBProxySBValue.h" |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: CMICmdCmdVarCreate constructor. |
| // Type: Method. |
| // Args: None. |
| // Return: None. |
| // Throws: None. |
| //-- |
| CMICmdCmdVarCreate::CMICmdCmdVarCreate( void ) |
| : m_nChildren( 0 ) |
| , m_nMore( 0 ) |
| , m_nThreadId( 0 ) |
| , m_strType( "??" ) |
| , m_bValid( false ) |
| , m_constStrArgThread( "thread" ) |
| , m_constStrArgThreadGroup( "thread-group" ) |
| , m_constStrArgFrame( "frame" ) |
| , 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( void ) |
| { |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // 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( void ) |
| { |
| bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgThread, false, true, CMICmdArgValListBase::eArgValType_Number, 1 ) ) ); |
| bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgThreadGroup, false, false, CMICmdArgValListBase::eArgValType_ThreadGrp, 1 ) ) ); |
| bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgFrame, false, true, CMICmdArgValListBase::eArgValType_Number, 1 ) ) ); |
| bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValString( m_constStrArgName, false, true ) ) ); |
| bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValString( m_constStrArgFrameAddr, false, true ) ) ); |
| bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValString( m_constStrArgExpression, true, true, true, true ) ) ); |
| CMICmdArgContext argCntxt( m_cmdData.strMiCmdOption ); |
| if( bOk && !m_setCmdArgs.Validate( m_cmdData.strMiCmd, argCntxt ) ) |
| { |
| SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_ARGS ), m_cmdData.strMiCmd.c_str(), m_setCmdArgs.GetErrorDescription().c_str() ) ); |
| return MIstatus::failure; |
| } |
| |
| return bOk; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // 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( void ) |
| { |
| 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->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; |
| } |
| m_nThreadId = nThreadId; |
| |
| // Retrieve the --frame option's number |
| MIuint64 nFrame = UINT64_MAX; |
| if( !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(); |
| } |
| |
| bool bAutoName = false; |
| const CMIUtilString strArgName; |
| if( pArgName->GetFound() ) |
| { |
| const CMIUtilString & rArg = pArgName->GetValue(); |
| bAutoName = (rArg == "-"); |
| } |
| |
| const CMIUtilString & rStrExpression( pArgExpression->GetValue() ); |
| m_strExpression = rStrExpression; |
| |
| CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() ); |
| m_strVarName = "unnamedvariable"; |
| if( bAutoName ) |
| { |
| m_strVarName = CMIUtilString::Format( "var%u", CMICmnLLDBDebugSessionInfoVarObj::VarObjIdGet() ); |
| CMICmnLLDBDebugSessionInfoVarObj::VarObjIdInc(); |
| } |
| lldb::SBProcess & rProcess = rSessionInfo.m_lldbProcess; |
| lldb::SBThread thread = rProcess.GetThreadByIndexID( nThreadId ); |
| lldb::SBFrame frame = thread.GetFrameAtIndex( nFrame ); |
| lldb::SBValue value = frame.FindVariable( rStrExpression.c_str() ); |
| if( !value.IsValid() ) |
| value = frame.EvaluateExpression( rStrExpression.c_str() ); |
| if( value.IsValid() ) |
| { |
| m_bValid = true; |
| m_nChildren = value.GetNumChildren(); |
| const MIchar * pCType = value.GetTypeName(); |
| m_strType = (pCType != nullptr) ? pCType : m_strType; |
| } |
| |
| if( m_bValid ) |
| { |
| // This gets added to CMICmnLLDBDebugSessionInfoVarObj static container of varObjs |
| CMICmnLLDBDebugSessionInfoVarObj varObj( rStrExpression, m_strVarName, value ); |
| } |
| |
| 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( void ) |
| { |
| 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 ); |
| CMICmnLLDBDebugSessionInfoVarObj varObj; |
| const bool bOk = CMICmnLLDBDebugSessionInfoVarObj::VarObjGet( m_strVarName, varObj ); MIunused( bOk ); |
| const CMICmnMIValueConst miValueConst3( varObj.GetValueFormatted() ); |
| 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; |
| } |
| |
| const CMICmnMIValueConst miValueConst( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_VARIABLE_CREATION_FAILED ), m_strExpression.c_str() ) ); |
| 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( void ) |
| { |
| return new CMICmdCmdVarCreate(); |
| } |
| |
| //--------------------------------------------------------------------------------------- |
| //--------------------------------------------------------------------------------------- |
| //--------------------------------------------------------------------------------------- |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: CMICmdCmdVarUpdate constructor. |
| // Type: Method. |
| // Args: None. |
| // Return: None. |
| // Throws: None. |
| //-- |
| CMICmdCmdVarUpdate::CMICmdCmdVarUpdate( void ) |
| : m_constStrArgPrintValues( "print-values" ) |
| , m_constStrArgName( "name" ) |
| , m_bValueChangedArrayType( false ) |
| , m_bValueChangedCompositeType( false ) |
| , m_bValueChangedNormalType( 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( void ) |
| { |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // 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( void ) |
| { |
| bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValNumber( m_constStrArgPrintValues, false, false ) ) ); |
| bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValString( m_constStrArgName, true, true ) ) ); |
| CMICmdArgContext argCntxt( m_cmdData.strMiCmdOption ); |
| if( bOk && !m_setCmdArgs.Validate( m_cmdData.strMiCmd, argCntxt ) ) |
| { |
| SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_ARGS ), m_cmdData.strMiCmd.c_str(), m_setCmdArgs.GetErrorDescription().c_str() ) ); |
| return MIstatus::failure; |
| } |
| |
| return bOk; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // 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( void ) |
| { |
| 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; |
| } |
| |
| const CMIUtilString & rVarRealName( varObj.GetNameReal() ); MIunused( rVarRealName ); |
| lldb::SBValue & rValue = const_cast< lldb::SBValue & >( varObj.GetValue() ); |
| const bool bValid = rValue.IsValid(); |
| if( bValid && rValue.GetValueDidChange() ) |
| { |
| m_bValueChangedNormalType = true; |
| varObj.UpdateValue(); |
| m_strValueName = rVarObjName; |
| return MIstatus::success; |
| } |
| |
| // Examine an array type variable |
| if( !ExamineSBValueForChange( varObj, false, m_bValueChangedArrayType ) ) |
| return MIstatus::failure; |
| |
| // Handle composite types i.e. struct or arrays |
| const MIuint nChildren = rValue.GetNumChildren(); |
| for( MIuint i = 0; i < nChildren; i++ ) |
| { |
| lldb::SBValue member = rValue.GetChildAtIndex( i ); |
| if( !member.IsValid() ) |
| continue; |
| |
| const CMIUtilString varName( CMIUtilString::Format( "%s.%s", rVarObjName.c_str(), member.GetName() ) ); |
| if( member.GetValueDidChange() ) |
| { |
| // Handle composite |
| const CMIUtilString strValue( CMICmnLLDBDebugSessionInfoVarObj::GetValueStringFormatted( member, CMICmnLLDBDebugSessionInfoVarObj::eVarFormat_Natural ) ); |
| const CMIUtilString strInScope( member.IsInScope() ? "true" : "false" ); |
| MIFormResponse( varName, strValue, strInScope ); |
| |
| m_bValueChangedCompositeType = true; |
| } |
| else |
| { |
| // Handle array of composites |
| CMICmnLLDBDebugSessionInfoVarObj varObj; |
| if( CMICmnLLDBDebugSessionInfoVarObj::VarObjGet( varName, varObj ) ) |
| { |
| bool bValueChanged = false; |
| if( ExamineSBValueForChange( varObj, true, bValueChanged ) ) |
| { |
| if( bValueChanged && CMICmnLLDBDebugSessionInfoVarObj::VarObjGet( varName, varObj ) ) |
| { |
| lldb::SBValue & rValue = const_cast< lldb::SBValue & >( varObj.GetValue() ); |
| const bool bValid = rValue.IsValid(); |
| const CMIUtilString strValue( bValid ? varObj.GetValueFormatted() : "<unknown>" ); |
| const CMIUtilString strInScope( (bValid && rValue.IsInScope()) ? "true" : "false" ); |
| MIFormResponse( varName, strValue, strInScope ); |
| |
| m_bValueChangedCompositeType = true; |
| } |
| } |
| else |
| 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 CMICmdCmdVarUpdate::Acknowledge( void ) |
| { |
| if( m_bValueChangedArrayType || m_bValueChangedNormalType ) |
| { |
| CMICmnLLDBDebugSessionInfoVarObj varObj; |
| CMICmnLLDBDebugSessionInfoVarObj::VarObjGet( m_strValueName, varObj ); |
| lldb::SBValue & rValue = const_cast< lldb::SBValue & >( varObj.GetValue() ); |
| const bool bValid = rValue.IsValid(); |
| const CMIUtilString strValue( bValid ? varObj.GetValueFormatted() : "<unknown>" ); |
| const CMIUtilString strInScope( (bValid && rValue.IsInScope()) ? "true" : "false" ); |
| |
| // MI print "%s^done,changelist=[{name=\"%s\",value=\"%s\",in_scope=\"%s\",type_changed=\"false\",has_more=\"0\"}]" |
| const CMICmnMIValueConst miValueConst( m_strValueName ); |
| CMICmnMIValueResult miValueResult( "name", miValueConst ); |
| CMICmnMIValueTuple miValueTuple( miValueResult ); |
| const CMICmnMIValueConst miValueConst2( strValue ); |
| CMICmnMIValueResult miValueResult2( "value", miValueConst2 ); |
| miValueTuple.Add( miValueResult2 ); |
| const CMICmnMIValueConst miValueConst3( strInScope ); |
| CMICmnMIValueResult miValueResult3( "in_scope", miValueConst3 ); |
| miValueTuple.Add( miValueResult3 ); |
| const CMICmnMIValueConst miValueConst4( "false" ); |
| CMICmnMIValueResult miValueResult4( "type_changed", miValueConst4 ); |
| miValueTuple.Add( miValueResult4 ); |
| const CMICmnMIValueConst miValueConst5( "0" ); |
| CMICmnMIValueResult miValueResult5( "has_more", miValueConst5 ); |
| miValueTuple.Add( miValueResult5 ); |
| const CMICmnMIValueList miValueList( miValueTuple ); |
| CMICmnMIValueResult miValueResult6( "changelist", miValueList ); |
| const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult6 ); |
| m_miResultRecord = miRecordResult; |
| |
| return MIstatus::success; |
| } |
| else if( m_bValueChangedCompositeType ) |
| { |
| // MI print "%s^done,changelist=[{name=\"%s\",value=\"%s\",in_scope=\"%s\",type_changed=\"false\",has_more=\"0\"},{name=\"%s\",value=\"%s\",in_scope=\"%s\",type_changed=\"false\",has_more=\"0\"}]" |
| CMICmnMIValueResult miValueResult6( "changelist", m_miValueList ); |
| const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult6 ); |
| m_miResultRecord = miRecordResult; |
| } |
| else |
| { |
| // MI: "%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; |
| } |
| |
| 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( void ) |
| { |
| return new CMICmdCmdVarUpdate(); |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: Form the MI response for multiple variables. |
| // Type: Method. |
| // Args: vrStrVarName - (R) Session var object's name. |
| // vrStrValue - (R) Text version of the value held in the variable. |
| // vrStrScope - (R) In scope "yes" or "no". |
| // Return: MIstatus::success - Functional succeeded. |
| // MIstatus::failure - Functional failed. |
| // Throws: None. |
| //-- |
| bool CMICmdCmdVarUpdate::MIFormResponse( const CMIUtilString & vrStrVarName, const CMIUtilString & vrStrValue, const CMIUtilString & vrStrScope ) |
| { |
| // MI print "[{name=\"%s\",value=\"%s\",in_scope=\"%s\",type_changed=\"false\",has_more=\"0\"}]" |
| const CMICmnMIValueConst miValueConst( vrStrVarName ); |
| CMICmnMIValueResult miValueResult( "name", miValueConst ); |
| CMICmnMIValueTuple miValueTuple( miValueResult ); |
| const CMICmnMIValueConst miValueConst2( vrStrValue ); |
| CMICmnMIValueResult miValueResult2( "value", miValueConst2 ); |
| bool bOk = miValueTuple.Add( miValueResult2 ); |
| const CMICmnMIValueConst miValueConst3( vrStrScope ); |
| CMICmnMIValueResult miValueResult3( "in_scope", miValueConst3 ); |
| bOk = bOk && miValueTuple.Add( miValueResult3 ); |
| const CMICmnMIValueConst miValueConst4( "false" ); |
| CMICmnMIValueResult miValueResult4( "type_changed", miValueConst4 ); |
| bOk = bOk && miValueTuple.Add( miValueResult4 ); |
| const CMICmnMIValueConst miValueConst5( "0" ); |
| CMICmnMIValueResult miValueResult5( "has_more", miValueConst5 ); |
| bOk = bOk && miValueTuple.Add( miValueResult5 ); |
| bOk = bOk && m_miValueList.Add( miValueTuple ); |
| |
| return bOk; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: Determine if the var object is a array type variable. LLDB does not 'detect' |
| // a value change for some types like elements in an array so have to re-evaluate |
| // the expression again. |
| // Type: Method. |
| // Args: vrVarObj - (R) Session var object to examine. |
| // vrwbChanged - (W) True = Is an array type and it changed, |
| // False = Not an array type or not changed. |
| // Return: MIstatus::success - Functional succeeded. |
| // MIstatus::failure - Functional failed. |
| // Throws: None. |
| //-- |
| bool CMICmdCmdVarUpdate::ExamineSBValueForChange( const CMICmnLLDBDebugSessionInfoVarObj & vrVarObj, const bool vbIgnoreVarType, bool & vrwbChanged ) |
| { |
| vrwbChanged = false; |
| |
| CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() ); |
| lldb::SBProcess & rProcess = rSessionInfo.m_lldbProcess; |
| lldb::SBThread thread = rProcess.GetSelectedThread(); |
| if( thread.GetNumFrames() == 0 ) |
| { |
| return MIstatus::success; |
| } |
| |
| const CMIUtilString & strVarObjParentName = vrVarObj.GetVarParentName(); |
| lldb::SBFrame frame = thread.GetSelectedFrame(); |
| const CMIUtilString & rExpression( vrVarObj.GetNameReal() ); |
| CMIUtilString varExpression; |
| if( strVarObjParentName.empty() ) |
| { |
| varExpression = rExpression; |
| } |
| else |
| { |
| CMICmnLLDBDebugSessionInfoVarObj varObjParent; |
| if( CMICmnLLDBDebugSessionInfoVarObj::VarObjGet( strVarObjParentName, varObjParent ) ) |
| varExpression = CMIUtilString::Format( "%s.%s", varObjParent.GetNameReal().c_str(), rExpression.c_str() ); |
| else |
| { |
| // The parent is only assigned in the CMICmdCmdVarListChildren command, we have a problem, need to investigate |
| SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_VARIABLE_DOESNOTEXIST ), m_cmdData.strMiCmd.c_str(), strVarObjParentName.c_str() ) ); |
| return MIstatus::failure; |
| } |
| } |
| |
| lldb::SBValue value = frame.EvaluateExpression( varExpression.c_str() ); |
| if( !value.IsValid() ) |
| value = frame.FindVariable( rExpression.c_str() ); |
| if( value.IsValid() ) |
| { |
| lldb::SBType valueType = value.GetType(); |
| const lldb::BasicType eValueType = valueType.GetBasicType(); |
| if( vbIgnoreVarType || (eValueType != lldb::BasicType::eBasicTypeInvalid) ) |
| { |
| MIuint64 nPrevValue = 0; |
| MIuint64 nRevaluateValue = 0; |
| lldb::SBValue & rValue = const_cast< lldb::SBValue & >( vrVarObj.GetValue() ); |
| if( CMICmnLLDBProxySBValue::GetValueAsUnsigned( rValue, nPrevValue ) && |
| CMICmnLLDBProxySBValue::GetValueAsUnsigned( value, nRevaluateValue ) && |
| (nPrevValue != nRevaluateValue) ) |
| { |
| // Have a value change so update the var object |
| vrwbChanged = true; |
| const CMICmnLLDBDebugSessionInfoVarObj varObj( rExpression, vrVarObj.GetName(), value, strVarObjParentName ); |
| } |
| } |
| } |
| |
| return MIstatus::success; |
| } |
| |
| //--------------------------------------------------------------------------------------- |
| //--------------------------------------------------------------------------------------- |
| //--------------------------------------------------------------------------------------- |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: CMICmdCmdVarDelete constructor. |
| // Type: Method. |
| // Args: None. |
| // Return: None. |
| // Throws: None. |
| //-- |
| CMICmdCmdVarDelete::CMICmdCmdVarDelete( void ) |
| : 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( void ) |
| { |
| bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValString( m_constStrArgName, true, true ) ) ); |
| CMICmdArgContext argCntxt( m_cmdData.strMiCmdOption ); |
| if( bOk && !m_setCmdArgs.Validate( m_cmdData.strMiCmd, argCntxt ) ) |
| { |
| SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_ARGS ), m_cmdData.strMiCmd.c_str(), m_setCmdArgs.GetErrorDescription().c_str() ) ); |
| return MIstatus::failure; |
| } |
| |
| return bOk; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: CMICmdCmdVarDelete destructor. |
| // Type: Overrideable. |
| // Args: None. |
| // Return: None. |
| // Throws: None. |
| //-- |
| CMICmdCmdVarDelete::~CMICmdCmdVarDelete( void ) |
| { |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // 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( void ) |
| { |
| 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( void ) |
| { |
| 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( void ) |
| { |
| return new CMICmdCmdVarDelete(); |
| } |
| |
| //--------------------------------------------------------------------------------------- |
| //--------------------------------------------------------------------------------------- |
| //--------------------------------------------------------------------------------------- |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: CMICmdCmdVarAssign constructor. |
| // Type: Method. |
| // Args: None. |
| // Return: None. |
| // Throws: None. |
| //-- |
| CMICmdCmdVarAssign::CMICmdCmdVarAssign( void ) |
| : 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( void ) |
| { |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // 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( void ) |
| { |
| bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValString( m_constStrArgName, true, true ) ) ); |
| bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValString( m_constStrArgExpression, true, true ) ) ); |
| CMICmdArgContext argCntxt( m_cmdData.strMiCmdOption ); |
| if( bOk && !m_setCmdArgs.Validate( m_cmdData.strMiCmd, argCntxt ) ) |
| { |
| SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_ARGS ), m_cmdData.strMiCmd.c_str(), m_setCmdArgs.GetErrorDescription().c_str() ) ); |
| return MIstatus::failure; |
| } |
| |
| return bOk; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // 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( void ) |
| { |
| 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( void ) |
| { |
| 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( void ) |
| { |
| return new CMICmdCmdVarAssign(); |
| } |
| |
| //--------------------------------------------------------------------------------------- |
| //--------------------------------------------------------------------------------------- |
| //--------------------------------------------------------------------------------------- |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: CMICmdCmdVarSetFormat constructor. |
| // Type: Method. |
| // Args: None. |
| // Return: None. |
| // Throws: None. |
| //-- |
| CMICmdCmdVarSetFormat::CMICmdCmdVarSetFormat( void ) |
| : 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( void ) |
| { |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // 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( void ) |
| { |
| bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValString( m_constStrArgName, true, true ) ) ); |
| bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValString( m_constStrArgFormatSpec, true, true ) ) ); |
| CMICmdArgContext argCntxt( m_cmdData.strMiCmdOption ); |
| if( bOk && !m_setCmdArgs.Validate( m_cmdData.strMiCmd, argCntxt ) ) |
| { |
| SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_ARGS ), m_cmdData.strMiCmd.c_str(), m_setCmdArgs.GetErrorDescription().c_str() ) ); |
| return MIstatus::failure; |
| } |
| |
| return bOk; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // 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( void ) |
| { |
| 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( void ) |
| { |
| // 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( void ) |
| { |
| return new CMICmdCmdVarSetFormat(); |
| } |
| |
| //--------------------------------------------------------------------------------------- |
| //--------------------------------------------------------------------------------------- |
| //--------------------------------------------------------------------------------------- |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: CMICmdCmdVarListChildren constructor. |
| // Type: Method. |
| // Args: None. |
| // Return: None. |
| // Throws: None. |
| //-- |
| CMICmdCmdVarListChildren::CMICmdCmdVarListChildren( void ) |
| : m_bValueValid( false ) |
| , m_nChildren( 0 ) |
| , m_constStrArgPrintValues( "print-values" ) |
| , m_constStrArgName( "name" ) |
| { |
| // 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( void ) |
| { |
| m_vecMiValueResult.clear(); |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // 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( void ) |
| { |
| bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValNumber( m_constStrArgPrintValues, false, false ) ) ); |
| bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValString( m_constStrArgName, true, true ) ) ); |
| CMICmdArgContext argCntxt( m_cmdData.strMiCmdOption ); |
| if( bOk && !m_setCmdArgs.Validate( m_cmdData.strMiCmd, argCntxt ) ) |
| { |
| SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_ARGS ), m_cmdData.strMiCmd.c_str(), m_setCmdArgs.GetErrorDescription().c_str() ) ); |
| return MIstatus::failure; |
| } |
| |
| return bOk; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // 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( void ) |
| { |
| 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_vecMiValueResult.clear(); |
| m_nChildren = rValue.GetNumChildren(); |
| for( MIuint i = 0; i < m_nChildren; i++ ) |
| { |
| lldb::SBValue member = rValue.GetChildAtIndex( i ); |
| if( !member.IsValid() ) |
| continue; |
| |
| const MIchar * pExp = member.GetName(); |
| const CMIUtilString strExp = (pExp != nullptr) ? pExp : "??"; |
| const CMIUtilString name( CMIUtilString::Format( "%s.%s", rVarObjName.c_str(), strExp.c_str() ) ); |
| const MIuint nChildren = member.GetNumChildren(); |
| const MIchar * pTypeName = member.GetType().GetName(); |
| const CMIUtilString strType = (pTypeName != nullptr) ? pTypeName : MIRSRC( IDS_WORD_UNKNOWNTYPE_BRKTS ); |
| 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( "%d", nChildren ) ); |
| const CMICmnMIValueConst miValueConst3( strNumChild ); |
| const CMICmnMIValueResult miValueResult3( "numchild", miValueConst3 ); |
| miValueTuple.Add( miValueResult3 ); |
| const CMICmnMIValueConst miValueConst5( strType ); |
| const CMICmnMIValueResult miValueResult5( "type", miValueConst5 ); |
| miValueTuple.Add( miValueResult5 ); |
| const CMICmnMIValueConst miValueConst6( strThreadId ); |
| const CMICmnMIValueResult miValueResult6( "thread-id", miValueConst6 ); |
| miValueTuple.Add( miValueResult6 ); |
| const CMICmnMIValueConst miValueConst7( "0" ); |
| const CMICmnMIValueResult miValueResult7( "has_more", miValueConst7 ); |
| miValueTuple.Add( miValueResult7 ); |
| const CMICmnMIValueResult miValueResult8( "child", miValueTuple ); |
| m_vecMiValueResult.push_back( miValueResult8 ); |
| } |
| |
| 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( void ) |
| { |
| if( m_bValueValid ) |
| { |
| // MI print "%s^done,numchild=\"%u\",children=[]"" |
| const CMIUtilString strNumChild( CMIUtilString::Format( "%u", m_nChildren ) ); |
| const CMICmnMIValueConst miValueConst( strNumChild ); |
| CMICmnMIValueResult miValueResult( "numchild", miValueConst ); |
| |
| VecMIValueResult_t::const_iterator it = m_vecMiValueResult.begin(); |
| if( it == m_vecMiValueResult.end() ) |
| { |
| const CMICmnMIValueConst miValueConst( "[]" ); |
| miValueResult.Add( "children", miValueConst ); |
| } |
| else |
| { |
| CMICmnMIValueList miValueList( *it ); |
| ++it; |
| while( it != m_vecMiValueResult.end() ) |
| { |
| const CMICmnMIValueResult & rResult( *it ); |
| miValueList.Add( rResult ); |
| |
| // Next |
| ++it; |
| } |
| miValueResult.Add( "children", miValueList ); |
| } |
| |
| const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult ); |
| m_miResultRecord = miRecordResult; |
| return MIstatus::success; |
| } |
| |
| // MI print "%s^done,numchild=\"0\"" |
| const CMICmnMIValueConst miValueConst( "0" ); |
| const CMICmnMIValueResult miValueResult( "numchild", 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 * CMICmdCmdVarListChildren::CreateSelf( void ) |
| { |
| return new CMICmdCmdVarListChildren(); |
| } |
| |
| //--------------------------------------------------------------------------------------- |
| //--------------------------------------------------------------------------------------- |
| //--------------------------------------------------------------------------------------- |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: CMICmdCmdVarEvaluateExpression constructor. |
| // Type: Method. |
| // Args: None. |
| // Return: None. |
| // Throws: None. |
| //-- |
| CMICmdCmdVarEvaluateExpression::CMICmdCmdVarEvaluateExpression( void ) |
| : 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( void ) |
| { |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // 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( void ) |
| { |
| bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValOptionShort( m_constStrArgFormatSpec, false, false, CMICmdArgValListBase::eArgValType_String, 1 ) ) ); |
| bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValString( m_constStrArgName, true, true ) ) ); |
| CMICmdArgContext argCntxt( m_cmdData.strMiCmdOption ); |
| if( bOk && !m_setCmdArgs.Validate( m_cmdData.strMiCmd, argCntxt ) ) |
| { |
| SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_ARGS ), m_cmdData.strMiCmd.c_str(), m_setCmdArgs.GetErrorDescription().c_str() ) ); |
| return MIstatus::failure; |
| } |
| |
| return bOk; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // 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( void ) |
| { |
| 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( void ) |
| { |
| 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( void ) |
| { |
| return new CMICmdCmdVarEvaluateExpression(); |
| } |
| |
| //--------------------------------------------------------------------------------------- |
| //--------------------------------------------------------------------------------------- |
| //--------------------------------------------------------------------------------------- |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: CMICmdCmdVarInfoPathExpression constructor. |
| // Type: Method. |
| // Args: None. |
| // Return: None. |
| // Throws: None. |
| //-- |
| CMICmdCmdVarInfoPathExpression::CMICmdCmdVarInfoPathExpression( void ) |
| : 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( void ) |
| { |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // 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( void ) |
| { |
| bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValString( m_constStrArgName, true, true ) ) ); |
| CMICmdArgContext argCntxt( m_cmdData.strMiCmdOption ); |
| if( bOk && !m_setCmdArgs.Validate( m_cmdData.strMiCmd, argCntxt ) ) |
| { |
| SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_ARGS ), m_cmdData.strMiCmd.c_str(), m_setCmdArgs.GetErrorDescription().c_str() ) ); |
| return MIstatus::failure; |
| } |
| |
| return bOk; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // 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( void ) |
| { |
| 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 MIchar * 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( void ) |
| { |
| 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( void ) |
| { |
| return new CMICmdCmdVarInfoPathExpression(); |
| } |
| |
| //--------------------------------------------------------------------------------------- |
| //--------------------------------------------------------------------------------------- |
| //--------------------------------------------------------------------------------------- |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: CMICmdCmdVarShowAttributes constructor. |
| // Type: Method. |
| // Args: None. |
| // Return: None. |
| // Throws: None. |
| //-- |
| CMICmdCmdVarShowAttributes::CMICmdCmdVarShowAttributes( void ) |
| : 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( void ) |
| { |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // 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( void ) |
| { |
| bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValString( m_constStrArgName, true, true ) ) ); |
| CMICmdArgContext argCntxt( m_cmdData.strMiCmdOption ); |
| if( bOk && !m_setCmdArgs.Validate( m_cmdData.strMiCmd, argCntxt ) ) |
| { |
| SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_ARGS ), m_cmdData.strMiCmd.c_str(), m_setCmdArgs.GetErrorDescription().c_str() ) ); |
| return MIstatus::failure; |
| } |
| |
| return bOk; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // 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( void ) |
| { |
| 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( void ) |
| { |
| // 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( void ) |
| { |
| return new CMICmdCmdVarShowAttributes(); |
| } |