//++ ------------------------------------------------------------------------------------
// Details: Form MI partial response by appending more MI value type objects to the
//          tuple type object past in.
// Type:    Method.
// Args:    vrThread        - (R) LLDB thread object.
//          vwrMIValueTuple - (W) MI value tuple object.
//          vArgInfo        - (R) Args information in MI response form.
// Return:  MIstatus::success - Functional succeeded.
//          MIstatus::failure - Functional failed.
// Throws:  None.
//--
bool
CMICmnLLDBDebugSessionInfo::MIResponseFormFrameInfo(const lldb::SBThread &vrThread, const MIuint vnLevel,
                                                    const FrameInfoFormat_e veFrameInfoFormat, CMICmnMIValueTuple &vwrMiValueTuple)
{
    lldb::SBThread &rThread = const_cast<lldb::SBThread &>(vrThread);

    lldb::SBFrame frame = rThread.GetFrameAtIndex(vnLevel);
    lldb::addr_t pc = 0;
    CMIUtilString fnName;
    CMIUtilString fileName;
    CMIUtilString path;
    MIuint nLine = 0;
    if (!GetFrameInfo(frame, pc, fnName, fileName, path, nLine))
        return MIstatus::failure;

    // MI print "{level=\"0\",addr=\"0x%016" PRIx64 "\",func=\"%s\",file=\"%s\",fullname=\"%s\",line=\"%d\"}"
    const CMIUtilString strLevel(CMIUtilString::Format("%d", vnLevel));
    const CMICmnMIValueConst miValueConst(strLevel);
    const CMICmnMIValueResult miValueResult("level", miValueConst);
    vwrMiValueTuple.Add(miValueResult);
    const CMIUtilString strAddr(CMIUtilString::Format("0x%016" PRIx64, pc));
    const CMICmnMIValueConst miValueConst2(strAddr);
    const CMICmnMIValueResult miValueResult2("addr", miValueConst2);
    vwrMiValueTuple.Add(miValueResult2);
    const CMICmnMIValueConst miValueConst3(fnName);
    const CMICmnMIValueResult miValueResult3("func", miValueConst3);
    vwrMiValueTuple.Add(miValueResult3);
    if (veFrameInfoFormat != eFrameInfoFormat_NoArguments)
    {
        CMICmnMIValueList miValueList(true);
        const MIuint maskVarTypes = eVariableType_Arguments;
        if (veFrameInfoFormat == eFrameInfoFormat_AllArgumentsInSimpleForm)
        {
            if (!MIResponseFormVariableInfo(frame, maskVarTypes, eVariableInfoFormat_AllValues, miValueList, 0))
                return MIstatus::failure;
        }
        else
            if (!MIResponseFormVariableInfo(frame, maskVarTypes, eVariableInfoFormat_AllValues, miValueList))
                return MIstatus::failure;

        const CMICmnMIValueResult miValueResult4("args", miValueList);
        vwrMiValueTuple.Add(miValueResult4);
    }
    const CMICmnMIValueConst miValueConst5(fileName);
    const CMICmnMIValueResult miValueResult5("file", miValueConst5);
    vwrMiValueTuple.Add(miValueResult5);
    const CMICmnMIValueConst miValueConst6(path);
    const CMICmnMIValueResult miValueResult6("fullname", miValueConst6);
    vwrMiValueTuple.Add(miValueResult6);
    const CMIUtilString strLine(CMIUtilString::Format("%d", nLine));
    const CMICmnMIValueConst miValueConst7(strLine);
    const CMICmnMIValueResult miValueResult7("line", miValueConst7);
    vwrMiValueTuple.Add(miValueResult7);

    return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// Details:	Form MI partial response by appending more MI value type objects to the 
//			tuple type object past in.
// Type:	Method.
// Args:	vrThread		- (R) LLDB thread object.
//			vwrMIValueTuple	- (W) MI value tuple object.
// Return:	MIstatus::success - Functional succeeded.
//			MIstatus::failure - Functional failed.
// Throws:	None.
//--
bool CMICmnLLDBDebugSessionInfo::MIResponseFormFrameInfo( const lldb::SBThread & vrThread, const MIuint vnLevel, CMICmnMIValueTuple & vwrMiValueTuple )
{
	lldb::SBThread & rThread = const_cast< lldb::SBThread & >( vrThread );
	
	lldb::SBFrame frame = rThread.GetFrameAtIndex( vnLevel );
	lldb::addr_t pc = 0;
	CMIUtilString fnName;
	CMIUtilString fileName;
	CMIUtilString path; 
	MIuint nLine = 0;
	if( !GetFrameInfo( frame, pc, fnName, fileName, path, nLine ) )
		return MIstatus::failure;
	
	CMICmnMIValueList miValueList( true );
	const MIuint vMaskVarTypes = 0x1000;
	if( !MIResponseFormVariableInfo( frame, vMaskVarTypes, miValueList ) )
		return MIstatus::failure;

	// MI print "{level=\"0\",addr=\"0x%08llx\",func=\"%s\",args=[%s],file=\"%s\",fullname=\"%s\",line=\"%d\"}"
	const CMIUtilString strLevel( CMIUtilString::Format( "%d", vnLevel ) );
	const CMICmnMIValueConst miValueConst( strLevel );
	const CMICmnMIValueResult miValueResult( "level", miValueConst );
	CMICmnMIValueTuple miValueTuple( miValueResult );
	if( !MIResponseFormFrameInfo( pc, fnName, miValueList.GetString(), fileName, path, nLine, miValueTuple ) )
		return MIstatus::failure;

	vwrMiValueTuple = miValueTuple;

	return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// Details:	Retrieve the specified thread's frame information.
// Type:	Method.
// Args:	vCmdData		- (R) A command's information.
//			vThreadIdx		- (R) Thread index.
//			vwrThreadFrames	- (W) Frame data.
// Return:	MIstatus::success - Functional succeeded.
//			MIstatus::failure - Functional failed.
// Throws:	None.
//--
bool CMICmnLLDBDebugSessionInfo::GetThreadFrames( const SMICmdData & vCmdData, const MIuint vThreadIdx, CMICmnMIValueTuple & vwrThreadFrames ) 
{
	lldb::SBThread thread = m_lldbProcess.GetThreadByIndexID( vThreadIdx );
	const uint32_t nFrames = thread.GetNumFrames();
	if( nFrames == 0 )
	{
		vwrThreadFrames = CMICmnMIValueTuple();
		return MIstatus::success;
	}

	CMICmnMIValueTuple miValueTupleAll;
	for( MIuint nLevel = 0; nLevel < nFrames; nLevel++ )
	{
		lldb::SBFrame frame = thread.GetFrameAtIndex( nLevel );
		lldb::addr_t pc = 0;
		CMIUtilString fnName;
		CMIUtilString fileName;
		CMIUtilString path; 
		MIuint nLine = 0;
		if( !GetFrameInfo( frame, pc, fnName, fileName, path, nLine ) )
			return MIstatus::failure;

		// Function args
		CMICmnMIValueList miValueList( true );
		const MIuint vMaskVarTypes = 0x1000;
		if( !MIResponseFormVariableInfo( frame, vMaskVarTypes, miValueList ) )
			return MIstatus::failure;

		const MIchar * pUnknown = "??";
		if( fnName != pUnknown )
		{
			std::replace( fnName.begin(), fnName.end(), ')', ' ' );
			std::replace( fnName.begin(), fnName.end(), '(', ' ' );
			std::replace( fnName.begin(), fnName.end(), '\'', ' ' );
		}

		const CMIUtilString strLevel( CMIUtilString::Format( "%d", nLevel ) );
		const CMICmnMIValueConst miValueConst( strLevel );
		const CMICmnMIValueResult miValueResult( "level", miValueConst );
		miValueTupleAll.Add( miValueResult );
		
		CMICmnMIValueTuple miValueTuple( miValueResult );
		if( !MIResponseFormFrameInfo( pc, fnName, miValueList.GetString(), fileName, path, nLine, miValueTuple ) )
			return MIstatus::failure;
	}

	vwrThreadFrames = miValueTupleAll;

	return MIstatus::success;
}