Example #1
0
//++ ------------------------------------------------------------------------------------
// Details: Execute commands from prepared source file
// 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;
}
Example #2
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:	Command instances can create and share data between other instances of commands.
//			This function adds new data to the shared data. Using the same ID more than
//			once replaces any previous matching data keys.
// Type:	Method.
// Args:	vKey	- (R) A non empty unique data key to retrieve by.
//			vData	- (R) Data to be added to the share.
// Return:	MIstatus::success - Functional succeeded.
//			MIstatus::failure - Functional failed.
// Throws:	None.
//--
bool CMICmnLLDBDebugSessionInfo::SharedDataAdd( const CMIUtilString & vKey, const CMIUtilString & vData )
{
	if( vKey.empty() )
		return MIstatus::failure;

	MapPairKeyToStringValue_t pr( vKey, vData );
	m_mapKeyToStringValue.insert( pr );

	return MIstatus::success;
}
Example #4
0
//++ ------------------------------------------------------------------------------------
// Details:	Set a unique ID for *this driver. It cannot be empty.
// Type:	Overridden.
// Args:	vId	- (R) Text description.
// Return:	MIstatus::success - Functional succeeded.
//			MIstatus::failure - Functional failed.
// Throws:	None.
//--
bool Driver::SetId( const CMIUtilString & vId )
{
	if( vId.empty() )
	{
		// Invalid to have it empty
		return MIstatus::failure;
	}

	m_strDriverId = vId;
	return MIstatus::success;
}
Example #5
0
//++ ------------------------------------------------------------------------------------
// Details:	Set a unique ID for *this driver. It cannot be empty.
// Type:	Overridden.
// Args:	vId	- (R) Text description.
// Return:	MIstatus::success - Functional succeeded.
//			MIstatus::failure - Functional failed.
// Throws:	None.
//--
bool CMIDriver::SetId( const CMIUtilString & vId )
{
	if( vId.empty() )
	{
		SetErrorDescriptionn( MIRSRC( IDS_DRIVER_ERR_ID_INVALID ), GetName().c_str(), vId.c_str() );
		return MIstatus::failure;
	}

	m_strDriverId = vId;
	return MIstatus::success;
}
Example #6
0
//++ ------------------------------------------------------------------------------------
// Details:	Given the SBBroadcaster class name save it's current event mask.
// Type:	Method.
// Args:	vBroadcasterClass	- (R) The SBBroadcaster's class name.
//			vEventMask			- (R) The mask of events to listen for.
// Return:	MIstatus::success - Functionality succeeded.
//			MIstatus::failure - Functionality failed.
// Throws:	None.
//--
bool CMICmnLLDBDebugger::BroadcasterSaveMask( const CMIUtilString & vBroadcasterClass, const MIuint vEventMask ) 
{
	if( vBroadcasterClass.empty() )
	{
		SetErrorDescription( CMIUtilString::Format( MIRSRC( IDS_LLDBDEBUGGER_ERR_INVALIDBROADCASTER ), vBroadcasterClass.c_str() ) );
		return MIstatus::failure;
	}

	BroadcasterRemoveMask( vBroadcasterClass );
	MapPairBroadcastClassNameToEventMask_t pr( vBroadcasterClass, vEventMask );
	m_mapBroadcastClassNameToEventMask.insert( pr );

	return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// Details: Validate and set the text that forms the prompt on the command line.
// Type:    Method.
// Args:    vNewPrompt  - (R) Text description.
// Return:  MIstatus::success - Functional succeeded.
//          MIstatus::failure - Functional failed.
// Throws:  None.
//--
bool
CMICmnStreamStdin::SetPrompt(const CMIUtilString &vNewPrompt)
{
    if (vNewPrompt.empty())
    {
        const CMIUtilString msg(CMIUtilString::Format(MIRSRC(IDS_STDIN_ERR_INVALID_PROMPT), vNewPrompt.c_str()));
        CMICmnStreamStdout::Instance().Write(msg);
        return MIstatus::failure;
    }

    m_strPromptCurrent = vNewPrompt;

    return MIstatus::success;
}
Example #8
0
//++ ------------------------------------------------------------------------------------
// Details:	Status on a file existing already.
// Type:	Method.
// Args:	vFileNamePath.
// Return:	True - Exists.
//			False - Not found.
// Throws:	None.
//--
bool CMIUtilFileStd::IsFileExist( const CMIUtilString & vFileNamePath ) const
{
	if( vFileNamePath.empty() )
		return false;

	FILE * pTmp = nullptr;
	pTmp = ::fopen( vFileNamePath.c_str(), "wb" );
	if( pTmp != nullptr )
	{
		::fclose( pTmp );
		return true;
	}

	return false;
}
Example #9
0
//++ ------------------------------------------------------------------------------------
// Details:	Check a command's name is valid:
//				- name is not empty
//				- name does not have spaces
// Type:	Method.
// Args:	vMiCmd	- (R) Command's name, the MI command.
// Return:	True - valid.
//			False - not valid.
// Throws:	None.
//--
bool CMICmdFactory::IsValid( const CMIUtilString & vMiCmd ) const
{
	bool bValid = true;

	if( vMiCmd.empty() )
	{
		bValid = false;
		return false;
	}

	const MIint nPos = vMiCmd.find( " " );
	if( nPos != (MIint) std::string::npos )
		bValid = false;
	
	return bValid;
}
Example #10
0
//++ ------------------------------------------------------------------------------------
// Details:	*this driver sits and waits for input to the stdin line queue shared by *this
//			driver and the stdin monitor thread, it queues, *this reads, interprets and
//			reacts.
//			This function is used by the application's main thread.
// Type:	Method.
// Args:	None.
// Return:	MIstatus::success - Functional succeeded.
//			MIstatus::failure - Functional failed.
// Throws:	None.
//--
bool CMIDriver::ReadStdinLineQueue( void )
{
	// True when queue contains input
	bool bHaveInput = false;

	// Stores the current input line
	CMIUtilString lineText;
	{
		// Lock while we access the queue
		CMIUtilThreadLock lock( m_threadMutex );
		if( !m_queueStdinLine.empty() )
		{
			lineText = m_queueStdinLine.front();
			m_queueStdinLine.pop();
			bHaveInput = !lineText.empty();
		}
	}

	// Process while we have input
	if( bHaveInput )
	{
		if( lineText == "quit" )
		{
			// We want to be exiting when receiving a quit command
			m_bExitApp = true;
			return MIstatus::success;
		}

		// Process the command
		const bool bOk = InterpretCommand( lineText );

		// Draw prompt if desired
		if( bOk && m_rStdin.GetEnablePrompt() )
			m_rStdOut.WriteMIResponse( m_rStdin.GetPrompt() );

		// Input has been processed
		bHaveInput = false;
	}
	else
	{
		// Give resources back to the OS
		const std::chrono::milliseconds time( 1 );
		std::this_thread::sleep_for( time );
	}
	
	return MIstatus::success;
}
Example #11
0
//++ ------------------------------------------------------------------------------------
// Details:	Given the client save its particular event requirements.
// Type:	Method.
// Args:	vClientName			- (R) The Client's unique ID.
//			vBroadcasterClass	- (R) The SBBroadcaster's class name targeted for the events.
//			vEventMask			- (R) The mask of events to listen for.
// Return:	MIstatus::success - Functionality succeeded.
//			MIstatus::failure - Functionality failed.
// Throws:	None.
//--
bool CMICmnLLDBDebugger::ClientSaveMask( const CMIUtilString & vClientName, const CMIUtilString & vBroadcasterClass, const MIuint vEventMask )
{
	if( vClientName.empty() )
	{
		SetErrorDescription( CMIUtilString::Format( MIRSRC( IDS_LLDBDEBUGGER_ERR_INVALIDCLIENTNAME ), vClientName.c_str() ) );
		return MIstatus::failure;
	}

	CMIUtilString strId( vBroadcasterClass );
	strId += vClientName;

	ClientRemoveTheirMask( vClientName, vBroadcasterClass );
	MapPairIdToEventMask_t pr( strId, vEventMask );
	m_mapIdToEventMask.insert( pr );

	return MIstatus::success;
}
Example #12
0
//++
//------------------------------------------------------------------------------------
// Details: Given the client remove it's particular event requirements.
// Type:    Method.
// Args:    vClientName       - (R) The Client's unique ID.
//          vBroadcasterClass - (R) The SBBroadcaster's class name.
// Return:  MIstatus::success - Functionality succeeded.
//          MIstatus::failure - Functionality failed.
// Throws:  None.
//--
bool CMICmnLLDBDebugger::ClientRemoveTheirMask(
    const CMIUtilString &vClientName, const CMIUtilString &vBroadcasterClass) {
  if (vClientName.empty()) {
    SetErrorDescription(CMIUtilString::Format(
        MIRSRC(IDS_LLDBDEBUGGER_ERR_INVALIDCLIENTNAME), vClientName.c_str()));
    return MIstatus::failure;
  }

  CMIUtilString strId(vBroadcasterClass);
  strId += vClientName;

  const MapIdToEventMask_t::const_iterator it = m_mapIdToEventMask.find(strId);
  if (it != m_mapIdToEventMask.end()) {
    m_mapIdToEventMask.erase(it);
  }

  return MIstatus::success;
}
Example #13
0
//++ ------------------------------------------------------------------------------------
// Details:	Given the SBBroadcaster class name retrieve it's current event mask.
// Type:	Method.
// Args:	vBroadcasterClass	- (R) The SBBroadcaster's class name.
//			vEventMask			- (W) The mask of events to listen for.
// Return:	MIstatus::success - Functionality succeeded.
//			MIstatus::failure - Functionality failed.
// Throws:	None.
//--
bool CMICmnLLDBDebugger::BroadcasterGetMask( const CMIUtilString & vBroadcasterClass, MIuint & vwEventMask ) const
{
	vwEventMask = 0;

	if( vBroadcasterClass.empty() )
	{
		SetErrorDescription( CMIUtilString::Format( MIRSRC( IDS_LLDBDEBUGGER_ERR_INVALIDBROADCASTER ), vBroadcasterClass.c_str() ) );
		return MIstatus::failure;
	}

	const MapBroadcastClassNameToEventMask_t::const_iterator it = m_mapBroadcastClassNameToEventMask.find( vBroadcasterClass );
	if( it != m_mapBroadcastClassNameToEventMask.end() )
	{
		vwEventMask = (*it).second;
	}

	return MIstatus::success;
}
Example #14
0
//++ ------------------------------------------------------------------------------------
// Details:	This function allows *this driver to call on another driver to perform work
//			should this driver not be able to handle the client data input.
//			SetDriverToFallThruTo() specifies the fall through to driver.
//			Check the error message if the function returns a failure.
// Type:	Overridden.
// Args:	vCmd		- (R) Command instruction to interpret.
//			vwErrMsg	- (W) Error description on command failing.
// Return:	MIstatus::success - Command succeeded.
//			MIstatus::failure - Command failed.
// Throws:	None.
//--
bool Driver::DoFallThruToAnotherDriver( const CMIUtilString & vCmd, CMIUtilString & vwErrMsg )
{
	bool bOk = MIstatus::success;
	vwErrMsg.empty();

	// ToDo: Implement do work on other driver after this driver said "Give up you try"
	// This may nto be required if the feature to 'fall through' is not required
	SBCommandReturnObject returnObj = lldb::SBCommandReturnObject();
	SBCommandInterpreter cmdIntrp = m_debugger.GetCommandInterpreter();
    const lldb::ReturnStatus cmdResult = cmdIntrp.HandleCommand( vCmd.c_str(), returnObj ); MIunused( cmdResult );
	if( returnObj.Succeeded() == false )
	{
		bOk = MIstatus::failure;
		vwErrMsg = returnObj.GetError();
	}
	
	return bOk;
}
Example #15
0
//++
// Details: Find and replace all matches of a sub string with another string. It
// does not
//          alter *this string.
// Type:    Method.
// Args:    vFind         - (R) The string to look for.
//          vReplaceWith  - (R) The string to replace the vFind match.
// Return:  CMIUtilString - New version of the string.
// Throws:  None.
//--
CMIUtilString
CMIUtilString::FindAndReplace(const CMIUtilString &vFind,
                              const CMIUtilString &vReplaceWith) const {
  if (vFind.empty() || this->empty())
    return *this;

  size_t nPos = find(vFind);
  if (nPos == std::string::npos)
    return *this;

  CMIUtilString strNew(*this);
  while (nPos != std::string::npos) {
    strNew.replace(nPos, vFind.length(), vReplaceWith);
    nPos += vReplaceWith.length();
    nPos = strNew.find(vFind, nPos);
  }

  return strNew;
}
Example #16
0
//++ ------------------------------------------------------------------------------------
// Details:	Splits string into array of strings using delimiter. If multiple delimiter
//			are found in sequence then they are not added to the list of splits.
// Type:	Method.
// Args:	vData		- (R) String data to be split up.
//			vDelimiter	- (R) Delimiter char or text.
//			vwVecSplits	- (W) Container of splits found in string data.
// Return:	MIuint - Number of splits found in the string data.
// Throws:	None.
//--
MIuint CMIUtilString::Split( const CMIUtilString & vDelimiter, VecString_t & vwVecSplits ) const
{
	vwVecSplits.clear();

	if( this->empty() || vDelimiter.empty() )
		return 0;

	MIint nPos = find( vDelimiter );
	if( nPos == (MIint) std::string::npos )
	{
		vwVecSplits.push_back( *this );
		return 1;
	}
	const MIint strLen( length() );
	if( nPos == strLen )
	{
		vwVecSplits.push_back( *this );
		return 1;
	}

	MIuint nAdd1( 1 );
	if( (nPos > 0) && (substr( 0, nPos ) != vDelimiter) )
	{
		nPos = 0;
		nAdd1 = 0;
	}
	MIint nPos2 = find( vDelimiter, nPos + 1 );
	while( nPos2 != (MIint) std::string::npos )
	{
		const MIuint len( nPos2 - nPos - nAdd1 );
		const std::string strSection( substr( nPos + nAdd1, len ) );
		if( strSection != vDelimiter )
			vwVecSplits.push_back( strSection.c_str() );
		nPos += len + 1;
		nPos2 = find( vDelimiter, nPos + 1 );
		nAdd1 = 0;
	}
	const std::string strSection( substr( nPos, strLen - nPos ) );
	if( (strSection.length() != 0) && (strSection != vDelimiter) )
		vwVecSplits.push_back( strSection.c_str() );
		
	return vwVecSplits.size();
}
Example #17
0
//++ ------------------------------------------------------------------------------------
// Details: Splits string into array of strings using delimiter. However the string is
//          also considered for text surrounded by quotes. Text with quotes including the
//          delimiter is treated as a whole. If multiple delimiter are found in sequence
//          then they are not added to the list of splits. Quotes that are embedded in
//          the string as string formatted quotes are ignored (proceeded by a '\\') i.e.
//          "\"MI GDB local C++.cpp\":88".
// Type:    Method.
// Args:    vData       - (R) String data to be split up.
//          vDelimiter  - (R) Delimiter char or text.
//          vwVecSplits - (W) Container of splits found in string data.
// Return:  size_t - Number of splits found in the string data.
// Throws:  None.
//--
size_t
CMIUtilString::SplitConsiderQuotes(const CMIUtilString &vDelimiter, VecString_t &vwVecSplits) const
{
    vwVecSplits.clear();

    if (this->empty() || vDelimiter.empty())
        return 0;

    const size_t nLen(length());
    size_t nOffset(0);
    do
    {
        // Find first occurrence which doesn't match to the delimiter
        const size_t nSectionPos(FindFirstNot(vDelimiter, nOffset));
        if (nSectionPos == std::string::npos)
            break;

        // Find next occurrence of the delimiter after (quoted) section
        const bool bSkipQuotedText(true);
        bool bUnmatchedQuote(false);
        size_t nNextDelimiterPos(FindFirst(vDelimiter, bSkipQuotedText, bUnmatchedQuote, nSectionPos));
        if (bUnmatchedQuote)
        {
            vwVecSplits.clear();
            return 0;
        }
        if (nNextDelimiterPos == std::string::npos)
            nNextDelimiterPos = nLen;

        // Extract string between delimiters
        const size_t nSectionLen(nNextDelimiterPos - nSectionPos);
        const std::string strSection(substr(nSectionPos, nSectionLen));
        vwVecSplits.push_back(strSection.c_str());

        // Next
        nOffset = nNextDelimiterPos + 1;
    }
    while (nOffset < nLen);

    return vwVecSplits.size();
}
Example #18
0
//++
//------------------------------------------------------------------------------------
// Details: Retrieve the client's event mask used for on a particular
// SBBroadcaster.
// Type:    Method.
// Args:    vClientName       - (R) The Client's unique ID.
//          vBroadcasterClass - (R) The SBBroadcaster's class name.
//          vwEventMask       - (W) The client's mask.
// Return:  MIstatus::success - Functionality succeeded.
//          MIstatus::failure - Functionality failed.
// Throws:  None.
//--
bool CMICmnLLDBDebugger::ClientGetTheirMask(
    const CMIUtilString &vClientName, const CMIUtilString &vBroadcasterClass,
    MIuint &vwEventMask) {
  vwEventMask = 0;

  if (vClientName.empty()) {
    SetErrorDescription(CMIUtilString::Format(
        MIRSRC(IDS_LLDBDEBUGGER_ERR_INVALIDCLIENTNAME), vClientName.c_str()));
    return MIstatus::failure;
  }

  const CMIUtilString strId(vBroadcasterClass + vClientName);
  const MapIdToEventMask_t::const_iterator it = m_mapIdToEventMask.find(strId);
  if (it != m_mapIdToEventMask.end()) {
    vwEventMask = (*it).second;
  }

  SetErrorDescription(CMIUtilString::Format(
      MIRSRC(IDS_LLDBDEBUGGER_ERR_CLIENTNOTREGISTERED), vClientName.c_str()));

  return MIstatus::failure;
}
//++
//------------------------------------------------------------------------------------
// Details: Retrieve from the LLDB SB Value object the value of the variable
// described in
//          text if it has a simple format (not composite).
// Type:    Method.
// Args:    vwrValue          - (W) The SBValue in a string format.
// Return:  MIstatus::success - Function succeeded.
//          MIstatus::failure - Function failed.
// Throws:  None.
//--
bool CMICmnLLDBUtilSBValue::GetSimpleValue(const bool vbHandleArrayType,
                                           CMIUtilString &vwrValue) const {
  const MIuint nChildren = m_rValue.GetNumChildren();
  if (nChildren == 0) {
    vwrValue = GetValueSummary(!m_bHandleCharType && IsCharType(), m_pUnkwn);
    return MIstatus::success;
  } else if (IsPointerType()) {
    vwrValue =
        GetValueSummary(!m_bHandleCharType && IsPointeeCharType(), m_pUnkwn);
    return MIstatus::success;
  } else if (IsArrayType()) {
    CMICmnLLDBDebugSessionInfo &rSessionInfo(
        CMICmnLLDBDebugSessionInfo::Instance());
    bool bPrintCharArrayAsString = false;
    bPrintCharArrayAsString = rSessionInfo.SharedDataRetrieve<bool>(
                                  rSessionInfo.m_constStrPrintCharArrayAsString,
                                  bPrintCharArrayAsString) &&
                              bPrintCharArrayAsString;
    if (bPrintCharArrayAsString && m_bHandleCharType &&
        IsFirstChildCharType()) {
      vwrValue = GetValueSummary(false);
      return MIstatus::success;
    } else if (vbHandleArrayType) {
      vwrValue = CMIUtilString::Format("[%u]", nChildren);
      return MIstatus::success;
    }
  } else {
    // Treat composite value which has registered summary
    // (for example with AddCXXSummary) as simple value
    vwrValue = GetValueSummary(false);
    if (!vwrValue.empty())
      return MIstatus::success;
  }

  // Composite variable type i.e. struct
  return MIstatus::failure;
}
Example #20
0
//++ ------------------------------------------------------------------------------------
// Details:	Open file for writing. On the first call to this function after *this object
//			is created the file is either created or replace, from then on open only opens
//			an existing file.
// Type:	Method.
// Args:	vFileNamePath	- (R) File name path.
//			vwrbNewCreated	- (W) True - file recreated, false - file appended too.
// Return:	MIstatus::success - Functional succeeded.
//			MIstatus::failure - Functional failed.
// Throws:	None.
//--
bool CMIUtilFileStd::CreateWrite( const CMIUtilString & vFileNamePath, bool & vwrbNewCreated )
{
	// Reset
	m_bFileError = false;
	vwrbNewCreated = false;
		
	if( vFileNamePath.empty() )
	{
		m_bFileError = true;
		SetErrorDescription( MIRSRC( IDS_UTIL_FILE_ERR_INVALID_PATHNAME ) );
		return MIstatus::failure;
	}
	
	// File is already open so exit
	if( m_pFileHandle != nullptr )
		return MIstatus::success;

#if !defined( _MSC_VER )
	// Open with 'write' and 'binary' mode
	m_pFileHandle = ::fopen( vFileNamePath.c_str(), "wb" );
#else
	// Open a file with exclusive write and shared read permissions
	m_pFileHandle = ::_fsopen( vFileNamePath.c_str(), "wb", _SH_DENYWR );
#endif // !defined( _MSC_VER )

	if( m_pFileHandle == nullptr )
	{
		m_bFileError = true;
		SetErrorDescriptionn( MIRSRC( IDS_UTIL_FILE_ERR_OPENING_FILE ), strerror( errno ), vFileNamePath.c_str() );
		return MIstatus::failure;
	}
	
	vwrbNewCreated = true;
	m_fileNamePath = vFileNamePath;

	return MIstatus::success;
}
Example #21
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 - Functional succeeded.
//          MIstatus::failure - Functional failed.
// Throws:  None.
//--
bool
CMICmdCmdBreakInsert::Execute()
{
    CMICMDBASE_GETOPTION(pArgTempBrkPt, OptionShort, m_constStrArgNamedTempBrkPt);
    CMICMDBASE_GETOPTION(pArgThreadGroup, OptionLong, m_constStrArgNamedThreadGroup);
    CMICMDBASE_GETOPTION(pArgLocation, String, m_constStrArgNamedLocation);
    CMICMDBASE_GETOPTION(pArgIgnoreCnt, OptionShort, m_constStrArgNamedInoreCnt);
    CMICMDBASE_GETOPTION(pArgPendingBrkPt, OptionShort, m_constStrArgNamedPendinfBrkPt);
    CMICMDBASE_GETOPTION(pArgDisableBrkPt, OptionShort, m_constStrArgNamedDisableBrkPt);
    CMICMDBASE_GETOPTION(pArgConditionalBrkPt, OptionShort, m_constStrArgNamedConditionalBrkPt);
    CMICMDBASE_GETOPTION(pArgRestrictBrkPtToThreadId, OptionShort, m_constStrArgNamedRestrictBrkPtToThreadId);

    m_bBrkPtEnabled = !pArgDisableBrkPt->GetFound();
    m_bBrkPtIsTemp = pArgTempBrkPt->GetFound();
    m_bHaveArgOptionThreadGrp = pArgThreadGroup->GetFound();
    if (m_bHaveArgOptionThreadGrp)
    {
        MIuint nThreadGrp = 0;
        pArgThreadGroup->GetExpectedOption<CMICmdArgValThreadGrp, MIuint>(nThreadGrp);
        m_strArgOptionThreadGrp = CMIUtilString::Format("i%d", nThreadGrp);
    }
    m_bBrkPtIsPending = pArgPendingBrkPt->GetFound();
    if (pArgLocation->GetFound())
        m_brkName = pArgLocation->GetValue();
    else if (m_bBrkPtIsPending)
    {
        pArgPendingBrkPt->GetExpectedOption<CMICmdArgValString, CMIUtilString>(m_brkName);
    }
    if (pArgIgnoreCnt->GetFound())
    {
        pArgIgnoreCnt->GetExpectedOption<CMICmdArgValNumber, MIuint>(m_nBrkPtIgnoreCount);
    }
    m_bBrkPtCondition = pArgConditionalBrkPt->GetFound();
    if (m_bBrkPtCondition)
    {
        pArgConditionalBrkPt->GetExpectedOption<CMICmdArgValString, CMIUtilString>(m_brkPtCondition);
    }
    m_bBrkPtThreadId = pArgRestrictBrkPtToThreadId->GetFound();
    if (m_bBrkPtCondition)
    {
        pArgRestrictBrkPtToThreadId->GetExpectedOption<CMICmdArgValNumber, MIuint>(m_nBrkPtThreadId);
    }

    // Determine if break on a file line or at a function
    BreakPoint_e eBrkPtType = eBreakPoint_NotDefineYet;
    CMIUtilString fileName;
    MIuint nFileLine = 0;
    CMIUtilString strFileFn;
    CMIUtilString rStrLineOrFn;
    // Is the string in the form 'file:func' or 'file:line'?
    // If so, find the position of the ':' separator.
    const size_t nPosColon = findFileSeparatorPos(m_brkName);
    if (nPosColon != std::string::npos)
    {
        // Extract file name and line number from it
        fileName = m_brkName.substr(0, nPosColon);
        rStrLineOrFn = m_brkName.substr(nPosColon + 1, m_brkName.size() - nPosColon - 1);

        if (rStrLineOrFn.empty())
            eBrkPtType = eBreakPoint_ByName;
        else
        {
            MIint64 nValue = 0;
            if (rStrLineOrFn.ExtractNumber(nValue))
            {
                nFileLine = static_cast<MIuint>(nValue);
                eBrkPtType = eBreakPoint_ByFileLine;
            }
            else
            {
                strFileFn = rStrLineOrFn;
                eBrkPtType = eBreakPoint_ByFileFn;
            }
        }
    }

    // Determine if break defined as an address
    lldb::addr_t nAddress = 0;
    if (eBrkPtType == eBreakPoint_NotDefineYet)
    {
        MIint64 nValue = 0;
        if (m_brkName.ExtractNumber(nValue))
        {
            nAddress = static_cast<lldb::addr_t>(nValue);
            eBrkPtType = eBreakPoint_ByAddress;
        }
    }

    // Break defined as an function
    if (eBrkPtType == eBreakPoint_NotDefineYet)
    {
        eBrkPtType = eBreakPoint_ByName;
    }

    // Ask LLDB to create a breakpoint
    bool bOk = MIstatus::success;
    CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
    lldb::SBTarget sbTarget = rSessionInfo.GetTarget();
    switch (eBrkPtType)
    {
        case eBreakPoint_ByAddress:
            m_brkPt = sbTarget.BreakpointCreateByAddress(nAddress);
            break;
        case eBreakPoint_ByFileFn:
        {
            lldb::SBFileSpecList module;    // search in all modules
            lldb::SBFileSpecList compUnit;
            compUnit.Append (lldb::SBFileSpec(fileName.c_str()));
            m_brkPt = sbTarget.BreakpointCreateByName(strFileFn.c_str(), module, compUnit);
            break;
        }
        case eBreakPoint_ByFileLine:
            m_brkPt = sbTarget.BreakpointCreateByLocation(fileName.c_str(), nFileLine);
            break;
        case eBreakPoint_ByName:
            m_brkPt = sbTarget.BreakpointCreateByName(m_brkName.c_str(), nullptr);
            break;
        case eBreakPoint_count:
        case eBreakPoint_NotDefineYet:
        case eBreakPoint_Invalid:
            bOk = MIstatus::failure;
            break;
    }

    if (bOk)
    {
        if (!m_bBrkPtIsPending && (m_brkPt.GetNumLocations() == 0))
        {
            sbTarget.BreakpointDelete(m_brkPt.GetID());
            SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_BRKPT_LOCATION_NOT_FOUND), m_cmdData.strMiCmd.c_str(), m_brkName.c_str()));
            return MIstatus::failure;
        }

        m_brkPt.SetEnabled(m_bBrkPtEnabled);
        m_brkPt.SetIgnoreCount(m_nBrkPtIgnoreCount);
        if (m_bBrkPtCondition)
            m_brkPt.SetCondition(m_brkPtCondition.c_str());
        if (m_bBrkPtThreadId)
            m_brkPt.SetThreadID(m_nBrkPtThreadId);
    }

    // CODETAG_LLDB_BREAKPOINT_CREATION
    // This is in the main thread
    // Record break point information to be by LLDB event handler function
    CMICmnLLDBDebugSessionInfo::SBrkPtInfo sBrkPtInfo;
    if (!rSessionInfo.GetBrkPtInfo(m_brkPt, sBrkPtInfo))
        return MIstatus::failure;
    sBrkPtInfo.m_id = m_brkPt.GetID();
    sBrkPtInfo.m_bDisp = m_bBrkPtIsTemp;
    sBrkPtInfo.m_bEnabled = m_bBrkPtEnabled;
    sBrkPtInfo.m_bHaveArgOptionThreadGrp = m_bHaveArgOptionThreadGrp;
    sBrkPtInfo.m_strOptThrdGrp = m_strArgOptionThreadGrp;
    sBrkPtInfo.m_nTimes = m_brkPt.GetHitCount();
    sBrkPtInfo.m_strOrigLoc = m_brkName;
    sBrkPtInfo.m_nIgnore = m_nBrkPtIgnoreCount;
    sBrkPtInfo.m_bPending = m_bBrkPtIsPending;
    sBrkPtInfo.m_bCondition = m_bBrkPtCondition;
    sBrkPtInfo.m_strCondition = m_brkPtCondition;
    sBrkPtInfo.m_bBrkPtThreadId = m_bBrkPtThreadId;
    sBrkPtInfo.m_nBrkPtThreadId = m_nBrkPtThreadId;

    bOk = bOk && rSessionInfo.RecordBrkPtInfo(m_brkPt.GetID(), sBrkPtInfo);
    if (!bOk)
    {
        SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_BRKPT_INVALID), m_cmdData.strMiCmd.c_str(), m_brkName.c_str()));
        return MIstatus::failure;
    }

    // CODETAG_LLDB_BRKPT_ID_MAX
    if (m_brkPt.GetID() > (lldb::break_id_t)rSessionInfo.m_nBrkPointCntMax)
    {
        SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_BRKPT_CNT_EXCEEDED), m_cmdData.strMiCmd.c_str(), rSessionInfo.m_nBrkPointCntMax,
                                       m_brkName.c_str()));
        return MIstatus::failure;
    }

    return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// Details: The monitoring on new line data calls back to the visitor object registered
//          with *this stdin monitoring. The monitoring to stops when the visitor returns
//          true for bYesExit flag. Errors output to log file.
//          This function runs in the thread "MI stdin monitor".
// Type:    Method.
//          vrwbYesAlive    - (W) False = yes exit stdin monitoring, true = continue monitor.
// Return:  MIstatus::success - Functional succeeded.
//          MIstatus::failure - Functional failed.
// Throws:  None.
//--
bool
CMICmnStreamStdin::MonitorStdin(bool &vrwbYesAlive)
{
    if (m_bShowPrompt)
    {
        CMICmnStreamStdout &rStdoutMan = CMICmnStreamStdout::Instance();
        rStdoutMan.WriteMIResponse(m_strPromptCurrent.c_str());
        m_bRedrawPrompt = false;
    }

    // CODETAG_DEBUG_SESSION_RUNNING_PROG_RECEIVED_SIGINT_PAUSE_PROGRAM
    if (m_bKeyCtrlCHit)
    {
        CMIDriver &rMIDriver = CMIDriver::Instance();
        rMIDriver.SetExitApplicationFlag(false);
        if (rMIDriver.GetExitApplicationFlag())
        {
            vrwbYesAlive = false;
            return MIstatus::success;
        }

        // Reset - the MI Driver received SIGINT during a running debug programm session
        m_bKeyCtrlCHit = false;
    }

#if MICONFIG_POLL_FOR_STD_IN
    bool bAvail = true;
    // Check if there is stdin available
    if (InputAvailable(bAvail))
    {
        // Early exit when there is no input
        if (!bAvail)
            return MIstatus::success;
    }
    else
    {
        vrwbYesAlive = false;
        CMIDriver::Instance().SetExitApplicationFlag(true);
        return MIstatus::failure;
    }
#endif // MICONFIG_POLL_FOR_STD_IN

    // Read a line from std input
    CMIUtilString stdinErrMsg;
    const MIchar *pText = ReadLine(stdinErrMsg);

    // Did something go wrong
    const bool bHaveError(!stdinErrMsg.empty());
    if ((pText == nullptr) || bHaveError)
    {
        if (bHaveError)
        {
            CMICmnStreamStdout::Instance().Write(stdinErrMsg);
        }
        return MIstatus::failure;
    }

    // We have text so send it off to the visitor
    bool bOk = MIstatus::success;
    if (m_pVisitor != nullptr)
    {
        bool bYesExit = false;
        bOk = m_pVisitor->ReadLine(CMIUtilString(pText), bYesExit);
        m_bRedrawPrompt = true;
        vrwbYesAlive = !bYesExit;
    }

    return bOk;
}
Example #23
0
//++ ------------------------------------------------------------------------------------
// Details:	Splits string into array of strings using delimiter. However the string is
//			also considered for text surrounded by quotes. Text with quotes including the
//			delimiter is treated as a whole. If multiple delimiter are found in sequence 
//			then they are not added to the list of splits.
// Type:	Method.
// Args:	vData		- (R) String data to be split up.
//			vDelimiter	- (R) Delimiter char or text.
//			vwVecSplits	- (W) Container of splits found in string data.
// Return:	MIuint - Number of splits found in the string data.
// Throws:	None.
//--
MIuint CMIUtilString::SplitConsiderQuotes( const CMIUtilString & vDelimiter, VecString_t & vwVecSplits ) const
{
	vwVecSplits.clear();

	if( this->empty() || vDelimiter.empty() )
		return 0;

	MIint nPos = find( vDelimiter );
	if( nPos == (MIint) std::string::npos )
	{
		vwVecSplits.push_back( *this );
		return 1;
	}
	const MIint strLen( length() );
	if( nPos == strLen )
	{
		vwVecSplits.push_back( *this );
		return 1;
	}

	// Look for more quotes
	bool bHaveQuotes = false;
	const MIchar cQuote = '"';
	MIint nPosQ = find( cQuote );
	MIint nPosQ2 = (MIint) std::string::npos;
	if( nPosQ != (MIint) std::string::npos )
	{
		nPosQ2 = find( cQuote, nPosQ + 1 );
		bHaveQuotes = (nPosQ2 != (MIint) std::string::npos);
	}

	MIuint nAdd1( 1 );
	if( (nPos > 0) && (substr( 0, nPos ) != vDelimiter) )
	{
		nPos = 0;
		nAdd1 = 0;
	}
	MIint nPos2 = find( vDelimiter, nPos + 1 );
	while( nPos2 != (MIint) std::string::npos )
	{
		if( !bHaveQuotes || (bHaveQuotes && ((nPos2 > nPosQ2) || (nPos2 < nPosQ))) )
		{
			// Extract text or quoted text
			const MIuint len( nPos2 - nPos - nAdd1 );
			const std::string strSection( substr( nPos + nAdd1, len ) );
			if( strSection != vDelimiter )
				vwVecSplits.push_back( strSection.c_str() );
			nPos += len + 1;
			nPos2 = find( vDelimiter, nPos + 1 );
			nAdd1 = 0;

			if( bHaveQuotes && (nPos2 > nPosQ2) )
			{
				// Reset, look for more quotes
				bHaveQuotes = false;
				nPosQ = find( cQuote, nPos );
				nPosQ2 = (MIint) std::string::npos;
				if( nPosQ != (MIint) std::string::npos )
				{
					nPosQ2 = find( cQuote, nPosQ + 1 );
					bHaveQuotes = (nPosQ2 != (MIint) std::string::npos);
				}
			}
		}
		else
		{
			// Skip passed text in quotes
			nPos2 = find( vDelimiter, nPosQ2 + 1 );
		}
	}
	const std::string strSection( substr( nPos, strLen - nPos ) );
	if( (strSection.length() != 0) && (strSection != vDelimiter) )
		vwVecSplits.push_back( strSection.c_str() );
		
	return vwVecSplits.size();
}