//++ ------------------------------------------------------------------------------------
// Details:	Examine the string and determine if it is a valid string type argument.
//			Take into account quotes surrounding the text. Note this function falls 
//			through to IsStringArgSingleText() should the criteria match fail.
// Type:	Method.
// Args:	vrTxt	- (R) Some text.
// Return:	bool -	True = yes valid arg, false = no.
// Throws:	None.
//--
bool CMICmdArgValString::IsStringArgQuotedText( const CMIUtilString & vrTxt ) const
{
	// CODETAG_QUOTEDTEXT_SIMILAR_CODE
	const MIchar cQuote = '"';
	const MIint nPos = vrTxt.find( cQuote );
	if( nPos == (MIint) std::string::npos )
		return false;

	// Is one and only quote at end of the string
	if( nPos == (MIint)(vrTxt.length() - 1) )
		return false;

	// Quote must be the first character in the string or be preceeded by a space
	// Also check for embedded string formating quote
	const MIchar cBckSlash = '\\'; 
	const MIchar cSpace = ' ';
	if( (nPos > 1) && (vrTxt[ nPos - 1 ] == cBckSlash) && (vrTxt[ nPos - 2 ] != cSpace) )
	{
		return false;
	}
	if( (nPos > 0) && (vrTxt[ nPos - 1 ] != cSpace) )
		return false;
	
	// Need to find the other quote
	const MIint nPos2 = vrTxt.rfind( cQuote );
	if( nPos2 == (MIint) std::string::npos )
		return false;

	// Make sure not same quote, need two quotes
	if( nPos == nPos2 )
		return MIstatus::failure;

	return true;
}
Exemple #2
0
//++ ------------------------------------------------------------------------------------
// Details:	Write data to existing opened file.
// Type:	Method.
// Args:	vData - (R) Text data.
// Return:	MIstatus::success - Functional succeeded.
//			MIstatus::failure - Functional failed.
// Throws:	None.
//--
bool CMIUtilFileStd::Write( const CMIUtilString & vData )
{
	if( vData.size() == 0 )
		return MIstatus::success;

	if( m_bFileError )
		return MIstatus::failure;

	if( m_pFileHandle == nullptr )
	{
		m_bFileError = true;
		SetErrorDescriptionn( MIRSRC( IDE_UTIL_FILE_ERR_WRITING_NOTOPEN ), m_fileNamePath.c_str() );
		return MIstatus::failure;
	}

	// Get the string size
	MIuint size = vData.size();
	if( ::fwrite( vData.c_str(), 1, size, m_pFileHandle ) == size )
	{
		// Flush the data to the file
		::fflush( m_pFileHandle );
		return MIstatus::success;
	}
	
	// Not all of the data has been transferred
	m_bFileError = true;
	SetErrorDescriptionn( MIRSRC( IDE_UTIL_FILE_ERR_WRITING_FILE ), m_fileNamePath.c_str() );
	return MIstatus::failure;
}
Exemple #3
0
//++ ------------------------------------------------------------------------------------
// 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 - Function succeeded.
//          MIstatus::failure - Function failed.
// Throws:  None.
//--
bool
CMICmdCmdExecArguments::Execute()
{
    CMICMDBASE_GETOPTION(pArgArguments, ListOfN, m_constStrArgArguments);

    CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
    lldb::SBTarget sbTarget = rSessionInfo.GetTarget();
    if (!sbTarget.IsValid())
    {
        SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INVALID_TARGET_CURRENT), m_cmdData.strMiCmd.c_str()));
        return MIstatus::failure;
    }

    lldb::SBLaunchInfo sbLaunchInfo = sbTarget.GetLaunchInfo();
    sbLaunchInfo.SetArguments(NULL, false);

    CMIUtilString strArg;
    size_t nArgIndex = 0;
    while (pArgArguments->GetExpectedOption<CMICmdArgValString, CMIUtilString>(strArg, nArgIndex))
    {
        const char *argv[2] = { strArg.c_str(), NULL };
        sbLaunchInfo.SetArguments(argv, true);
        ++nArgIndex;
    }

    sbTarget.SetLaunchInfo(sbLaunchInfo);

    return MIstatus::success;
}
//++
//------------------------------------------------------------------------------------
// 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 CMICmdCmdBreakAfter::Execute() {
  CMICMDBASE_GETOPTION(pArgNumber, Number, m_constStrArgNamedNumber);
  CMICMDBASE_GETOPTION(pArgCount, Number, m_constStrArgNamedCount);

  m_nBrkPtId = pArgNumber->GetValue();
  m_nBrkPtCount = pArgCount->GetValue();

  CMICmnLLDBDebugSessionInfo &rSessionInfo(
      CMICmnLLDBDebugSessionInfo::Instance());
  lldb::SBBreakpoint brkPt = rSessionInfo.GetTarget().FindBreakpointByID(
      static_cast<lldb::break_id_t>(m_nBrkPtId));
  if (brkPt.IsValid()) {
    brkPt.SetIgnoreCount(m_nBrkPtCount);

    CMICmnLLDBDebugSessionInfo::SBrkPtInfo sBrkPtInfo;
    if (!rSessionInfo.RecordBrkPtInfoGet(m_nBrkPtId, sBrkPtInfo)) {
      SetError(
          CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_BRKPT_INFO_OBJ_NOT_FOUND),
                                m_cmdData.strMiCmd.c_str(), m_nBrkPtId));
      return MIstatus::failure;
    }
    sBrkPtInfo.m_nIgnore = m_nBrkPtCount;
    rSessionInfo.RecordBrkPtInfo(m_nBrkPtId, sBrkPtInfo);
  } else {
    const CMIUtilString strBrkPtId(CMIUtilString::Format("%d", m_nBrkPtId));
    SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_BRKPT_INVALID),
                                   m_cmdData.strMiCmd.c_str(),
                                   strBrkPtId.c_str()));
    return MIstatus::failure;
  }

  return MIstatus::success;
}
//++
//------------------------------------------------------------------------------------
// 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 CMICmdCmdBreakDelete::Execute() {
  CMICMDBASE_GETOPTION(pArgBrkPt, ListOfN, m_constStrArgNamedBrkPt);

  // ATM we only handle one break point ID
  MIuint64 nBrk = UINT64_MAX;
  if (!pArgBrkPt->GetExpectedOption<CMICmdArgValNumber, MIuint64>(nBrk)) {
    SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_BRKPT_INVALID),
                                   m_cmdData.strMiCmd.c_str(),
                                   m_constStrArgNamedBrkPt.c_str()));
    return MIstatus::failure;
  }

  CMICmnLLDBDebugSessionInfo &rSessionInfo(
      CMICmnLLDBDebugSessionInfo::Instance());
  const bool bBrkPt = rSessionInfo.GetTarget().BreakpointDelete(
      static_cast<lldb::break_id_t>(nBrk));
  if (!bBrkPt) {
    const CMIUtilString strBrkNum(CMIUtilString::Format("%d", nBrk));
    SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_BRKPT_INVALID),
                                   m_cmdData.strMiCmd.c_str(),
                                   strBrkNum.c_str()));
    return MIstatus::failure;
  }

  return MIstatus::success;
}
//++
//------------------------------------------------------------------------------------
// 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 CMICmdCmdBreakCondition::Execute() {
  CMICMDBASE_GETOPTION(pArgNumber, Number, m_constStrArgNamedNumber);
  CMICMDBASE_GETOPTION(pArgExpr, String, m_constStrArgNamedExpr);

  m_nBrkPtId = pArgNumber->GetValue();
  m_strBrkPtExpr = pArgExpr->GetValue();
  m_strBrkPtExpr += GetRestOfExpressionNotSurroundedInQuotes();

  CMICmnLLDBDebugSessionInfo &rSessionInfo(
      CMICmnLLDBDebugSessionInfo::Instance());
  lldb::SBBreakpoint brkPt = rSessionInfo.GetTarget().FindBreakpointByID(
      static_cast<lldb::break_id_t>(m_nBrkPtId));
  if (brkPt.IsValid()) {
    brkPt.SetCondition(m_strBrkPtExpr.c_str());

    CMICmnLLDBDebugSessionInfo::SBrkPtInfo sBrkPtInfo;
    if (!rSessionInfo.RecordBrkPtInfoGet(m_nBrkPtId, sBrkPtInfo)) {
      SetError(
          CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_BRKPT_INFO_OBJ_NOT_FOUND),
                                m_cmdData.strMiCmd.c_str(), m_nBrkPtId));
      return MIstatus::failure;
    }
    sBrkPtInfo.m_strCondition = m_strBrkPtExpr;
    rSessionInfo.RecordBrkPtInfo(m_nBrkPtId, sBrkPtInfo);
  } else {
    const CMIUtilString strBrkPtId(CMIUtilString::Format("%d", m_nBrkPtId));
    SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_BRKPT_INVALID),
                                   m_cmdData.strMiCmd.c_str(),
                                   strBrkPtId.c_str()));
    return MIstatus::failure;
  }

  return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// Details: Release resources for *this Stdin stream.
// Type:    Method.
// Args:    None.
// Return:  MIstatus::success - Functional succeeded.
//          MIstatus::failure - Functional failed.
// Throws:  None.
//--
bool
CMICmnStreamStdin::Shutdown(void)
{
    if (--m_clientUsageRefCnt > 0)
        return MIstatus::success;

    if (!m_bInitialized)
        return MIstatus::success;

    m_bInitialized = false;

    ClrErrorDescription();

    if (m_pCmdBuffer != nullptr)
    {
        delete[] m_pCmdBuffer;
        m_pCmdBuffer = nullptr;
    }

    bool bOk = MIstatus::success;
    CMIUtilString errMsg;

    MI::ModuleShutdown<CMICmnResources>(IDE_MI_SHTDWN_ERR_RESOURCES, bOk, errMsg);
    MI::ModuleShutdown<CMICmnLog>(IDS_MI_SHTDWN_ERR_LOG, bOk, errMsg);

    if (!bOk)
    {
        SetErrorDescriptionn(MIRSRC(IDE_MI_SHTDWN_ERR_STREAMSTDIN), errMsg.c_str());
    }

    return MIstatus::success;
}
Exemple #8
0
//++ ------------------------------------------------------------------------------------
// Details:	A breakpoint expression can be passed to *this command as:
//				a single string i.e. '2' -> ok.
//				a quoted string i.e. "a > 100" -> ok
//				a non quoted string i.e. 'a > 100' -> not ok 
//			CMICmdArgValString only extracts the first space seperated string, the "a".
//			This function using the optional argument type CMICmdArgValListOfN collects 
//			the rest of the expression so that is may be added to the 'a' part to form a
//			complete expression string i.e. "a > 100".
//			If the expression value was guaranteed to be surrounded by quotes them this 
//			function would not be necessary.
// Type:	Method.
// Args:	None.
// Return:	CMIUtilString - Rest of the breakpoint expression.
// Throws:	None.
//--
CMIUtilString CMICmdCmdBreakCondition::GetRestOfExpressionNotSurroundedInQuotes( void )
{
	CMIUtilString strExpression;
		
	CMICmdArgValListOfN * pArgExprNoQuotes = CMICmdBase::GetOption< CMICmdArgValListOfN >( m_constStrArgNamedExprNoQuotes );
	if( pArgExprNoQuotes != nullptr )
	{
		CMIUtilString strExpression;
		const CMICmdArgValListBase::VecArgObjPtr_t & rVecExprParts( pArgExprNoQuotes->GetExpectedOptions() );
		if( !rVecExprParts.empty() )
		{
			CMICmdArgValListBase::VecArgObjPtr_t::const_iterator it = rVecExprParts.begin();
			while( it != rVecExprParts.end() )
			{
				const CMICmdArgValString * pPartExpr = static_cast< CMICmdArgValString * >( *it );
				const CMIUtilString & rPartExpr = pPartExpr->GetValue();
				strExpression += " ";
				strExpression += rPartExpr;

				// Next
				++it;
			}
			strExpression = strExpression.Trim();
		}
	}

	return strExpression;
}
//++ ------------------------------------------------------------------------------------
// Details: Examine the string and determine if it is a valid string type argument.
// Type:    Method.
// Args:    vrTxt   - (R) Some text.
// Return:  bool -  True = yes valid arg, false = no.
// Throws:  None.
//--
bool
CMICmdArgValListOfN::IsListOfN(const CMIUtilString &vrTxt) const
{
    CMIUtilString::VecString_t vecOptions;
    if ((m_eArgType == eArgValType_StringQuoted) || (m_eArgType == eArgValType_StringQuotedNumber) ||
        (m_eArgType == eArgValType_StringQuotedNumberPath) || (m_eArgType == eArgValType_StringAnything))
    {
        if (vrTxt.SplitConsiderQuotes(" ", vecOptions) == 0)
            return false;
    }
    else if (vrTxt.Split(" ", vecOptions) == 0)
        return false;

    CMIUtilString::VecString_t::const_iterator it = vecOptions.begin();
    while (it != vecOptions.end())
    {
        const CMIUtilString &rOption = *it;
        if (!IsExpectedCorrectType(rOption, m_eArgType))
            break;

        // Next
        ++it;
    }

    return true;
}
Exemple #10
0
//++
// Details: Set MI's error condition description. This may be accessed by
// clients and
//          seen by users.  Message is available to the client using the server
//          and sent
//          to the Logger.
// Type:    Method.
// Args:    vrTxt   - (R) Text description.
// Return:  None.
// Throws:  None.
//--
void CMICmnBase::SetErrorDescription(const CMIUtilString &vrTxt) const {
  m_strMILastErrorDescription = vrTxt;
  if (!vrTxt.empty()) {
    const CMIUtilString txt(CMIUtilString::Format("Error: %s", vrTxt.c_str()));
    CMICmnStreamStderr::Instance().Write(txt);
  }
}
//++
//------------------------------------------------------------------------------------
// Details: Release resources for *this thread manager.
// Type:    Method.
// Args:    None.
// Return:  MIstatus::success - Functional succeeded.
//          MIstatus::failure - Functional failed.
// Throws:  None.
//--
bool CMICmnThreadMgrStd::Shutdown() {
  if (--m_clientUsageRefCnt > 0)
    return MIstatus::success;

  if (!m_bInitialized)
    return MIstatus::success;

  m_bInitialized = false;

  ClrErrorDescription();

  bool bOk = MIstatus::success;
  CMIUtilString errMsg;

  // Tidy up
  ThreadAllTerminate();

  // Note shutdown order is important here
  MI::ModuleShutdown<CMICmnResources>(IDE_MI_SHTDWN_ERR_RESOURCES, bOk, errMsg);
  MI::ModuleShutdown<CMICmnLog>(IDS_MI_SHTDWN_ERR_LOG, bOk, errMsg);

  if (!bOk) {
    SetErrorDescriptionn(MIRSRC(IDS_MI_SHUTDOWN_ERR), errMsg.c_str());
  }

  return bOk;
}
//++
//------------------------------------------------------------------------------------
// Details: Unregister with the debugger, the SBListener, the type of events you
// are no
//          longer interested in. Others, like commands, may still remain
//          interested so
//          an event may not necessarily be stopped.
// Type:    Method.
// Args:    vClientName         - (R) ID of the client who no longer requires
// these events.
//          vBroadcasterClass   - (R) The SBBroadcaster's class name.
// Return:  MIstatus::success - Functionality succeeded.
//          MIstatus::failure - Functionality failed.
// Throws:  None.
//--
bool CMICmnLLDBDebugger::UnregisterForEvent(
    const CMIUtilString &vClientName, const CMIUtilString &vBroadcasterClass) {
  MIuint clientsEventMask = 0;
  if (!ClientGetTheirMask(vClientName, vBroadcasterClass, clientsEventMask))
    return MIstatus::failure;
  if (!ClientRemoveTheirMask(vClientName, vBroadcasterClass))
    return MIstatus::failure;

  const MIuint otherClientsEventMask =
      ClientGetMaskForAllClients(vBroadcasterClass);
  MIuint newEventMask = 0;
  for (MIuint i = 0; i < 32; i++) {
    const MIuint bit = 1 << i;
    const MIuint clientBit = bit & clientsEventMask;
    const MIuint othersBit = bit & otherClientsEventMask;
    if ((clientBit != 0) && (othersBit == 0)) {
      newEventMask += clientBit;
    }
  }

  const char *pBroadCasterName = vBroadcasterClass.c_str();
  if (!m_lldbListener.StopListeningForEventClass(
          m_lldbDebugger, pBroadCasterName, newEventMask)) {
    SetErrorDescription(
        CMIUtilString::Format(MIRSRC(IDS_LLDBDEBUGGER_ERR_STOPLISTENER),
                              vClientName.c_str(), pBroadCasterName));
    return MIstatus::failure;
  }

  return BroadcasterSaveMask(vBroadcasterClass, otherClientsEventMask);
}
//++ ------------------------------------------------------------------------------------
// Details:	Release resources for *this Stdin stream.
// Type:	Method.
// Args:	None.
// Return:	MIstatus::success - Functional succeeded.
//			MIstatus::failure - Functional failed.
// Throws:	None.
//--
bool CMICmnStreamStdinLinux::Shutdown( void )
{
	if( !m_bInitialized )
		return MIstatus::success;

	m_bInitialized = false;

	ClrErrorDescription();

	bool bOk = MIstatus::success;
	CMIUtilString errMsg;

	// Tidy up
	if( m_pCmdBuffer != nullptr )
	{
		delete [] m_pCmdBuffer;
		m_pCmdBuffer = nullptr;
	}
	m_pStdin = nullptr;

	// Note shutdown order is important here 	
	MI::ModuleShutdown< CMICmnResources >( IDS_MI_INIT_ERR_RESOURCES, bOk, errMsg );
	MI::ModuleShutdown< CMICmnLog >      ( IDS_MI_INIT_ERR_LOG      , bOk, errMsg );

	if( !bOk )
	{
		SetErrorDescriptionn( MIRSRC( IDS_MI_SHTDWN_ERR_OS_STDIN_HANDLER ), errMsg.c_str() );
	}

	return MIstatus::success;
}	
//++
//------------------------------------------------------------------------------------
// Details: Initialise resources for *this thread manager.
// Type:    Method.
// Args:    None.
// Return:  MIstatus::success - Functional succeeded.
//          MIstatus::failure - Functional failed.
// Throws:  None.
//--
bool CMICmnThreadMgrStd::Initialize() {
  m_clientUsageRefCnt++;

  if (m_bInitialized)
    return MIstatus::success;

  bool bOk = MIstatus::success;

  ClrErrorDescription();
  CMIUtilString errMsg;

  // Note initialisation order is important here as some resources depend on
  // previous
  MI::ModuleInit<CMICmnLog>(IDS_MI_INIT_ERR_LOG, bOk, errMsg);
  MI::ModuleInit<CMICmnResources>(IDS_MI_INIT_ERR_RESOURCES, bOk, errMsg);

  m_bInitialized = bOk;

  if (!bOk) {
    CMIUtilString strInitError(CMIUtilString::Format(
        MIRSRC(IDS_MI_INIT_ERR_THREADMGR), errMsg.c_str()));
    SetErrorDescription(strInitError);
    return MIstatus::failure;
  }

  return bOk;
}
//++ ------------------------------------------------------------------------------------
// Details:	Form MI partial response by appending more MI value type objects to the 
//			tuple type object past in.
// Type:	Method.
// Args:	vPc				- (R) Address number.
//			vFnName			- (R) Function name.
//			vFileName		- (R) File name text.
//			vPath			- (R) Full file name and path text.
//			vnLine			- (R) File line number.
//			vwrMIValueTuple	- (W) MI value tuple object.
// Return:	MIstatus::success - Functional succeeded.
//			MIstatus::failure - Functional failed.
// Throws:	None.
//--
bool CMICmnLLDBDebugSessionInfo::MIResponseFormBrkPtFrameInfo( const lldb::addr_t vPc, const CMIUtilString & vFnName, const CMIUtilString & vFileName, const CMIUtilString & vPath, const MIuint vnLine, CMICmnMIValueTuple & vwrMiValueTuple )
{
	const CMIUtilString strAddr( CMIUtilString::Format( "0x%08llx", vPc ) );
	const CMICmnMIValueConst miValueConst2( strAddr );
	const CMICmnMIValueResult miValueResult2( "addr", miValueConst2 );
	if( !vwrMiValueTuple.Add( miValueResult2 ) )
		return MIstatus::failure;
	const CMICmnMIValueConst miValueConst3( vFnName );
	const CMICmnMIValueResult miValueResult3( "func", miValueConst3 );
	if( !vwrMiValueTuple.Add( miValueResult3 ) )
		return MIstatus::failure;
	const CMICmnMIValueConst miValueConst5( vFileName );
	const CMICmnMIValueResult miValueResult5( "file", miValueConst5 );
	if( !vwrMiValueTuple.Add( miValueResult5 ) )
		return MIstatus::failure;
	const CMIUtilString strN5 = CMIUtilString::Format( "%s/%s", vPath.c_str(), vFileName.c_str() );
	const CMICmnMIValueConst miValueConst6( strN5 );
	const CMICmnMIValueResult miValueResult6( "fullname", miValueConst6 );
	if( !vwrMiValueTuple.Add( miValueResult6 ) )
		return MIstatus::failure;
	const CMIUtilString strLine( CMIUtilString::Format( "%d", vnLine ) );
	const CMICmnMIValueConst miValueConst7( strLine );
	const CMICmnMIValueResult miValueResult7( "line", miValueConst7 );
	if( !vwrMiValueTuple.Add( miValueResult7 ) )
		return MIstatus::failure;

	return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// Details: Create list of argument objects each holding a value extract from the command
//          options line.
// Type:    Method.
// Args:    vrTxt   - (R) Some options text.
// Return:  bool -  True = yes valid arg, false = no.
// Throws:  None.
//--
bool
CMICmdArgValListOfN::CreateList(const CMIUtilString &vrTxt)
{
    CMIUtilString::VecString_t vecOptions;
    if ((m_eArgType == eArgValType_StringQuoted) || (m_eArgType == eArgValType_StringQuotedNumber) ||
        (m_eArgType == eArgValType_StringQuotedNumberPath) || (m_eArgType == eArgValType_StringAnything))
    {
        if (vrTxt.SplitConsiderQuotes(" ", vecOptions) == 0)
            return MIstatus::failure;
    }
    else if (vrTxt.Split(" ", vecOptions) == 0)
        return MIstatus::failure;

    CMIUtilString::VecString_t::const_iterator it = vecOptions.begin();
    while (it != vecOptions.end())
    {
        const CMIUtilString &rOption = *it;
        CMICmdArgValBase *pOption = CreationObj(rOption, m_eArgType);
        if (pOption != nullptr)
            m_argValue.push_back(pOption);
        else
            return MIstatus::failure;

        // Next
        ++it;
    }

    return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// Details:	Parse the command's argument options string and try to extract all the words
//			between quotes then delimited by the next space. If there any string format
//			characters '\\' used to embed quotes these are ignored i.e. "\\\"%5d\\\""
//			becomes "%5d".
// Type:	Method.
// Args:	vrwArgContext	- (RW) The command's argument options string.
// Return:	MIstatus::success - Functional succeeded.
//			MIstatus::failure - Functional failed.
// Throws:	None.
//--
bool CMICmdArgValString::ValidateQuotedQuotedTextEmbedded( CMICmdArgContext & vrwArgContext )
{
	// CODETAG_QUOTEDTEXT_SIMILAR_CODE
	CMIUtilString strOptions = vrwArgContext.GetArgsLeftToParse();
	const MIint nPos = strOptions.find( "\"\\\"" );
	if( nPos == (MIint) std::string::npos )
		return MIstatus::failure;

	const MIint nPos2 = strOptions.rfind( "\\\"\"" );
	if( nPos2 == (MIint) std::string::npos )
		return MIstatus::failure;

	const MIint nLen = strOptions.length();
	if( (nLen > 5) && ((nPos + 2) == (nPos2 - 2)) )
		return MIstatus::failure;

	// Quote must be the first character in the string or be preceeded by a space
	// or '\\'
	const MIchar cSpace = ' ';
	if( (nPos > 0) && (strOptions[ nPos - 1 ] != cSpace) )
		return MIstatus::failure;

	// Extract quoted text
	const CMIUtilString strQuotedTxt = strOptions.substr( nPos, nPos2 - nPos + 3 ).c_str();
	if( vrwArgContext.RemoveArg( strQuotedTxt ) )
	{
		m_bFound = true;
		m_bValid = true;
		m_argValue = strQuotedTxt;	
		return MIstatus::success;
	}

	return MIstatus::failure;
}
Exemple #18
0
//++ ------------------------------------------------------------------------------------
// Details:	Interpret the text data and match against current commands to see if there 
//			is a match. If a match then the command is issued and actioned on. If a
//			command cannot be found to match then vwbCmdYesValid is set to false and
//			nothing else is done here.
//			This function is used by the application's main thread.
// Type:	Method.
// Args:	vTextLine			- (R) Text data representing a possible command.
//			vwbCmdYesValid		- (W) True = Command invalid, false = command acted on.
// Return:	MIstatus::success - Functional succeeded.
//			MIstatus::failure - Functional failed.
// Throws:	None.
//--
bool CMIDriver::InterpretCommandThisDriver( const CMIUtilString & vTextLine, bool & vwbCmdYesValid )
{
	vwbCmdYesValid = false;

	bool bCmdNotInCmdFactor = false;
	SMICmdData cmdData;
	CMICmdMgr & rCmdMgr = CMICmdMgr::Instance();
	if( !rCmdMgr.CmdInterpret( vTextLine, vwbCmdYesValid, bCmdNotInCmdFactor, cmdData ) )
		return MIstatus::failure;
	
	if( vwbCmdYesValid )
	{
		// For debugging only
		//m_pLog->WriteLog( cmdData.strMiCmdAll.c_str() );
		
		return ExecuteCommand( cmdData );
	}

	// Write to the Log that a 'command' was not valid. 
	// Report back to the MI client via MI result record.
	CMIUtilString strNotInCmdFactory;
	if( bCmdNotInCmdFactor )
		strNotInCmdFactory = CMIUtilString::Format( MIRSRC( IDS_DRIVER_CMD_NOT_IN_FACTORY ), cmdData.strMiCmd.c_str() );
	const CMIUtilString strNot( CMIUtilString::Format( "%s ", MIRSRC( IDS_WORD_NOT ) ) );
	const CMIUtilString msg( CMIUtilString::Format( MIRSRC( IDS_DRIVER_CMD_RECEIVED ), vTextLine.c_str(), strNot.c_str(), strNotInCmdFactory.c_str() ) );
	const CMICmnMIValueConst vconst = CMICmnMIValueConst( msg );
	const CMICmnMIValueResult valueResult( "msg", vconst );
	const CMICmnMIResultRecord miResultRecord( cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, valueResult );
	m_rStdOut.WriteMIResponse( miResultRecord.GetString() );
	
	// Proceed to wait for or execute next command
	return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// Details: Unbind detach or release resources used by *this driver.
// Type:    Method.
// Args:    None.
// Return:  MIstatus::success - Functional succeeded.
//          MIstatus::failure - Functional failed.
// Throws:  None.
//--
bool
CMIDriver::Shutdown(void)
{
    if (--m_clientUsageRefCnt > 0)
        return MIstatus::success;

    if (!m_bInitialized)
        return MIstatus::success;

    m_eCurrentDriverState = eDriverState_ShuttingDown;

    ClrErrorDescription();

    bool bOk = MIstatus::success;
    CMIUtilString errMsg;

    // Shutdown all of the modules we depend on
    MI::ModuleShutdown<CMICmnLLDBDebugger>(IDS_MI_INIT_ERR_LLDBDEBUGGER, bOk, errMsg);
    MI::ModuleShutdown<CMICmdMgr>(IDS_MI_INIT_ERR_CMDMGR, bOk, errMsg);
    MI::ModuleShutdown<CMICmnStreamStdin>(IDS_MI_INIT_ERR_STREAMSTDIN, bOk, errMsg);
    MI::ModuleShutdown<CMICmnThreadMgrStd>(IDS_MI_INIT_ERR_THREADMANAGER, bOk, errMsg);
    MI::ModuleShutdown<CMICmnResources>(IDS_MI_INIT_ERR_RESOURCES, bOk, errMsg);
    MI::ModuleShutdown<CMICmnStreamStderr>(IDS_MI_INIT_ERR_STREAMSTDERR, bOk, errMsg);
    MI::ModuleShutdown<CMICmnStreamStdout>(IDS_MI_INIT_ERR_STREAMSTDOUT, bOk, errMsg);
    MI::ModuleShutdown<CMICmnLog>(IDS_MI_INIT_ERR_LOG, bOk, errMsg);

    if (!bOk)
    {
        SetErrorDescriptionn(MIRSRC(IDS_MI_SHUTDOWN_ERR), errMsg.c_str());
    }

    m_eCurrentDriverState = eDriverState_NotRunning;

    return bOk;
}
Exemple #20
0
//++ ------------------------------------------------------------------------------------
// Details:	Determine and form the medium file's directory path and name.
// Type:	Method.
// Args:	None.
// Return:	MIstatus::success - Functional succeeded.
//			MIstatus::failure - Functional failed.
// Throws:	None.
//--
bool CMICmnLogMediumFile::FileFormFileNamePath( void )
{
	ClrErrorDescription();

	m_fileNamePath = MIRSRC( IDS_MEDIUMFILE_ERR_INVALID_PATH );

	CMIUtilString strPathName;
	if( CMIUtilSystem().GetLogFilesPath( strPathName ) )
	{
		const CMIUtilString strPath = CMIUtilFileStd().StripOffFileName( strPathName );

		// ToDo: Review this LINUX log file quick fix so not hidden
        // AD: 
        //      Linux was creating a log file here called '.\log.txt'.  The '.' on linux
        //      signifies that this file is 'hidden' and not normally visible.  A quick fix
        //      is to remove the path component all together.  Linux also normally uses '/'
        //      as directory separators, again leading to the problem of the hidden log.
#if defined ( _MSC_VER )
        m_fileNamePath = CMIUtilString::Format( "%s\\%s", strPath.c_str(), m_constMediumFileName.c_str() );
#else
        m_fileNamePath = CMIUtilString::Format( "%s", m_constMediumFileName.c_str() );
#endif // defined ( _MSC_VER )

		return MIstatus::success;
	}

	SetErrorDescription( MIRSRC( IDE_MEDIUMFILE_ERR_GET_FILE_PATHNAME_SYS ) );
	
	return MIstatus::failure;
}
//++ ------------------------------------------------------------------------------------
// Details: Write text data to stderr. The text data does not need to
//          include a carriage line return as this is added to the text. The function also
//          then passes the text data into the CMICmnLog logger.
// Type:    Method.
// Args:    vText           - (R) Text data. May be prefixed with MI app's short name.
//          vTxtForLogFile  - (R) Text data.
//          vbSendToLog     - (R) True = Yes send to the Log file too, false = do not. (Dflt = true)
// Return:  MIstatus::success - Functional succeeded.
//          MIstatus::failure - Functional failed.
// Throws:  None.
//--
bool
CMICmnStreamStderr::WritePriv(const CMIUtilString &vText, const CMIUtilString &vTxtForLogFile, const bool vbSendToLog /* = true */)
{
    if (vText.length() == 0)
        return MIstatus::failure;

    bool bOk = MIstatus::success;
    {
        // Grab the stderr thread lock while we print
        CMIUtilThreadLock _lock(m_mutex);

        // Send this text to stderr
        const MIint status = ::fputs(vText.c_str(), stderr);
        if (status == EOF)
        {
            const CMIUtilString errMsg(CMIUtilString::Format(MIRSRC(IDS_STDERR_ERR_NOT_ALL_DATA_WRITTEN), vText.c_str()));
            SetErrorDescription(errMsg);
            bOk = MIstatus::failure;
        }
        else
        {
            ::fprintf(stderr, "\n");
            ::fflush(stderr);
        }

        // Send this text to the log
        if (bOk && vbSendToLog)
            bOk &= m_pLog->WriteLog(vTxtForLogFile);
    }

    return bOk;
}
Exemple #22
0
//++
// Details: Check if two strings share equal contents.
// Type:    Method.
// Args:    vrLhs   - (R) String A.
//          vrRhs   - (R) String B.
// Return:  bool - True = yes equal, false - different.
// Throws:  None.
//--
bool CMIUtilString::Compare(const CMIUtilString &vrLhs,
                            const CMIUtilString &vrRhs) {
  // Check the sizes match
  if (vrLhs.size() != vrRhs.size())
    return false;

  return (::strncmp(vrLhs.c_str(), vrRhs.c_str(), vrLhs.size()) == 0);
}
Exemple #23
0
//++
//------------------------------------------------------------------------------------
// Details: Show a dialog to the process/application halts. It gives the
// opportunity to
//          attach a debugger.
// Type:    Static method.
// Args:    None.
// Return:  None.
// Throws:  None.
//--
void CMIUtilDebug::ShowDlgWaitForDbgAttach() {
  const CMIUtilString strCaption(CMIDriver::Instance().GetAppNameShort());
#ifdef _WIN32
  ::MessageBoxA(NULL, "Attach your debugger now", strCaption.c_str(), MB_OK);
#else
// ToDo: Implement other platform version of an Ok to continue dialog box
#endif // _WIN32
}
@@ -509,7 +509,7 @@ bool CMIDriver::StartWorkerThreads() {
    const CMIUtilString errMsg = CMIUtilString::Format(
                                     MIRSRC(IDS_THREADMGR_ERR_THREAD_FAIL_CREATE),
                                     CMICmnThreadMgrStd::Instance().GetErrorDescription().c_str());
    -    SetErrorDescriptionn(errMsg);
    +    SetErrorDescriptionn(errMsg.c_str());
    return MIstatus::failure;
}
//++ ------------------------------------------------------------------------------------
// Details: Execute commands from command source file in specified mode, and
//          set exit-flag if needed.
// Type:    Method.
// Args:    vbAsyncMode       - (R) True = execute commands in asynchronous mode, false = otherwise.
// Return:  MIstatus::success - Function succeeded.
//          MIstatus::failure - Function failed.
// Throws:  None.
//--
bool
CMIDriver::ExecuteCommandFile(const bool vbAsyncMode)
{
    std::ifstream ifsStartScript(m_strCmdLineArgCommandFileNamePath.c_str());
    if (!ifsStartScript.is_open())
    {
        const CMIUtilString errMsg(
            CMIUtilString::Format(MIRSRC(IDS_UTIL_FILE_ERR_OPENING_FILE_UNKNOWN), m_strCmdLineArgCommandFileNamePath.c_str()));
        SetErrorDescription(errMsg.c_str());
        const bool bForceExit = true;
        SetExitApplicationFlag(bForceExit);
        return MIstatus::failure;
    }

    // Switch lldb to synchronous mode
    CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
    const bool bAsyncSetting = rSessionInfo.GetDebugger().GetAsync();
    rSessionInfo.GetDebugger().SetAsync(vbAsyncMode);

    // Execute commands from file
    bool bOk = MIstatus::success;
    CMIUtilString strCommand;
    while (!m_bExitApp && std::getline(ifsStartScript, strCommand))
    {
        // Print command
        bOk = CMICmnStreamStdout::TextToStdout(strCommand);

        // Skip if it's a comment or empty line
        if (strCommand.empty() || strCommand[0] == '#')
            continue;

        // Execute if no error
        if (bOk)
        {
            CMIUtilThreadLock lock(rSessionInfo.GetSessionMutex());
            bOk = InterpretCommand(strCommand);
        }

        // Draw the prompt after command will be executed (if enabled)
        bOk = bOk && CMICmnStreamStdout::WritePrompt();

        // Exit if there is an error
        if (!bOk)
        {
            const bool bForceExit = true;
            SetExitApplicationFlag(bForceExit);
            break;
        }

        // Wait while the handler thread handles incoming events
        CMICmnLLDBDebugger::Instance().WaitForHandleEvent();
    }

    // Switch lldb back to initial mode
    rSessionInfo.GetDebugger().SetAsync(bAsyncSetting);

    return bOk;
}
Exemple #26
0
//++ ------------------------------------------------------------------------------------
// Details:	Write an LLDB text message to stderr.
//			The text data does not need to include a carrage line return as this is added
//			to the text. The function also then passes the text data into the CMICmnLog
//			logger.
// Type:	Method.
// Args:	vText		- (R) Text data.
//			vbSendToLog	- (R) True = Yes send to the Log file too, false = do not. (Dflt = true)
// Return:	MIstatus::success - Functional succeeded.
//			MIstatus::failure - Functional failed.
// Throws:	None.
//--
bool CMICmnStreamStderr::WriteLLDBMsg( const CMIUtilString & vText, const bool vbSendToLog /* = true */ )
{
    if( vText.length() == 0 )
        return MIstatus::failure;

    const CMIUtilString strPrefixed( CMIUtilString::Format( "LLDB: %s", vText.c_str() ) );

    return WritePriv( vText, strPrefixed, vbSendToLog );
}
Exemple #27
0
//++ ------------------------------------------------------------------------------------
// Details:	Initialize setup *this driver ready for use.
// Type:	Method.
// Args:	None.
// Return:	MIstatus::success - Functional succeeded.
//			MIstatus::failure - Functional failed.
// Throws:	None.
//--
bool CMIDriver::Initialize( void )
{
	m_eCurrentDriverState = eDriverState_Initialising;
	m_clientUsageRefCnt++;

	ClrErrorDescription();

	if( m_bInitialized )
		return MIstatus::success;

	bool bOk = MIstatus::success;
	CMIUtilString errMsg;

	// Initialize all of the modules we depend on
	MI::ModuleInit< CMICmnLog >         ( IDS_MI_INIT_ERR_LOG          , bOk, errMsg );
	MI::ModuleInit< CMICmnStreamStdout >( IDS_MI_INIT_ERR_STREAMSTDOUT , bOk, errMsg );
	MI::ModuleInit< CMICmnStreamStderr >( IDS_MI_INIT_ERR_STREAMSTDERR , bOk, errMsg );
	MI::ModuleInit< CMICmnResources >   ( IDS_MI_INIT_ERR_RESOURCES    , bOk, errMsg );
	MI::ModuleInit< CMICmnThreadMgrStd >( IDS_MI_INIT_ERR_THREADMANAGER, bOk, errMsg );
	MI::ModuleInit< CMICmnStreamStdin > ( IDS_MI_INIT_ERR_STREAMSTDIN  , bOk, errMsg );
	MI::ModuleInit< CMICmdMgr >         ( IDS_MI_INIT_ERR_CMDMGR       , bOk, errMsg );
	bOk &= m_rLldbDebugger.SetDriver( *this );
	MI::ModuleInit< CMICmnLLDBDebugger >( IDS_MI_INIT_ERR_LLDBDEBUGGER , bOk, errMsg );

#if MICONFIG_COMPILE_MIDRIVER_WITH_LLDBDRIVER
	CMIDriverMgr & rDrvMgr = CMIDriverMgr::Instance();
	bOk = bOk && rDrvMgr.RegisterDriver( *g_driver, "LLDB driver" );	// Will be pass thru driver
	if( bOk )
	{
		bOk = SetEnableFallThru( false ); // This is intentional at this time - yet to be fully implemented
		bOk = bOk && SetDriverToFallThruTo( *g_driver );
		CMIUtilString strOtherDrvErrMsg;
		if( bOk && GetEnableFallThru() && !g_driver->MISetup( strOtherDrvErrMsg ) )
		{
			bOk = false;
			errMsg = CMIUtilString::Format( MIRSRC( IDS_MI_INIT_ERR_FALLTHRUDRIVER ), strOtherDrvErrMsg.c_str()  );
		}
	}
#endif // MICONFIG_COMPILE_MIDRIVER_WITH_LLDBDRIVER

	m_bExitApp = false;
	bOk = bOk && InitClientIDEToMIDriver(); // Init Eclipse IDE
		
	m_bInitialized = bOk;

	if( !bOk )
	{
		const CMIUtilString msg = CMIUtilString::Format( MIRSRC( IDS_MI_INIT_ERR_DRIVER ), errMsg.c_str() );
		SetErrorDescription( msg );
		return MIstatus::failure;
	}

	m_eCurrentDriverState = eDriverState_RunningNotDebugging;
	
	return bOk;
}
Exemple #28
0
//++ ------------------------------------------------------------------------------------
// Details: Remove the argument from the options text and any space after the argument
//          if applicable.
// Type:    Method.
// Args:    vArg    - (R) The name of the argument.
// Return:  MIstatus::success - Functional succeeded.
//          MIstatus::failure - Functional failed.
// Throws:  None.
//--
bool
CMICmdArgContext::RemoveArg(const CMIUtilString &vArg)
{
    if (vArg.empty())
        return MIstatus::success;

    const size_t nLen = vArg.length();
    const size_t nLenCntxt = m_strCmdArgsAndOptions.length();
    if (nLen > nLenCntxt)
        return MIstatus::failure;

    size_t nExtraSpace = 0;
    size_t nPos = m_strCmdArgsAndOptions.find(vArg);
    while (1)
    {
        if (nPos == std::string::npos)
            return MIstatus::success;

        bool bPass1 = false;
        if (nPos != 0)
        {
            if (m_strCmdArgsAndOptions[nPos - 1] == ' ')
                bPass1 = true;
        }
        else
            bPass1 = true;

        const size_t nEnd = nPos + nLen;

        if (bPass1)
        {
            bool bPass2 = false;
            if (nEnd < nLenCntxt)
            {
                if (m_strCmdArgsAndOptions[nEnd] == ' ')
                {
                    bPass2 = true;
                    nExtraSpace = 1;
                }
            }
            else
                bPass2 = true;

            if (bPass2)
                break;
        }

        nPos = m_strCmdArgsAndOptions.find(vArg, nEnd);
    }

    const size_t nPosEnd = nLen + nExtraSpace;
    m_strCmdArgsAndOptions = m_strCmdArgsAndOptions.replace(nPos, nPosEnd, "");
    m_strCmdArgsAndOptions = m_strCmdArgsAndOptions.Trim();

    return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// Details:	Determine the given file path exists or not.
// Type:	Method.
// Args:	vPath				- (R) File name path.
//			vwbYesAccessible	- (W) True - file exists, false = does not exist.
// Return:	MIstatus::success - Functional succeeded.
//			MIstatus::failure - Functional failed.
// Throws:	None.
//--
bool CMICmnLLDBDebugSessionInfo::AccessPath( const CMIUtilString & vPath, bool & vwbYesAccessible )
{
#ifdef _WIN32
	vwbYesAccessible = (::_access( vPath.c_str(), 0 ) == 0);
#else
	vwbYesAccessible = (::access( vPath.c_str(), 0 ) == 0);
#endif // _WIN32

	return MIstatus::success;
}
Exemple #30
0
//++ ------------------------------------------------------------------------------------
// Details: Initialize resources for *this debugger object.
// Type:    Method.
// Args:    None.
// Return:  MIstatus::success - Functionality succeeded.
//          MIstatus::failure - Functionality failed.
// Throws:  None.
//--
bool
CMICmnLLDBDebugger::Initialize()
{
    m_clientUsageRefCnt++;

    if (m_bInitialized)
        return MIstatus::success;

    bool bOk = MIstatus::success;
    CMIUtilString errMsg;
    ClrErrorDescription();

    if (m_pClientDriver == nullptr)
    {
        bOk = false;
        errMsg = MIRSRC(IDS_LLDBDEBUGGER_ERR_CLIENTDRIVER);
    }

    // Note initialization order is important here as some resources depend on previous
    MI::ModuleInit<CMICmnLog>(IDS_MI_INIT_ERR_LOG, bOk, errMsg);
    MI::ModuleInit<CMICmnResources>(IDS_MI_INIT_ERR_RESOURCES, bOk, errMsg);
    MI::ModuleInit<CMICmnThreadMgrStd>(IDS_MI_INIT_ERR_THREADMGR, bOk, errMsg);
    MI::ModuleInit<CMICmnLLDBDebuggerHandleEvents>(IDS_MI_INIT_ERR_OUTOFBANDHANDLER, bOk, errMsg);
    MI::ModuleInit<CMICmnLLDBDebugSessionInfo>(IDS_MI_INIT_ERR_DEBUGSESSIONINFO, bOk, errMsg);

    // Note order is important here!
    if (bOk)
        lldb::SBDebugger::Initialize();
    if (bOk && !InitSBDebugger())
    {
        bOk = false;
        if (!errMsg.empty())
            errMsg += ", ";
        errMsg += GetErrorDescription().c_str();
    }
    if (bOk && !InitSBListener())
    {
        bOk = false;
        if (!errMsg.empty())
            errMsg += ", ";
        errMsg += GetErrorDescription().c_str();
    }
    bOk = bOk && InitStdStreams();
    bOk = bOk && RegisterMISummaryProviders();
    m_bInitialized = bOk;

    if (!bOk && !HaveErrorDescription())
    {
        CMIUtilString strInitError(CMIUtilString::Format(MIRSRC(IDS_MI_INIT_ERR_LLDBDEBUGGER), errMsg.c_str()));
        SetErrorDescription(strInitError);
    }

    return bOk;
}