diff options
Diffstat (limited to 'tools/lldb-mi/MIDriverMgr.cpp')
-rw-r--r-- | tools/lldb-mi/MIDriverMgr.cpp | 762 |
1 files changed, 762 insertions, 0 deletions
diff --git a/tools/lldb-mi/MIDriverMgr.cpp b/tools/lldb-mi/MIDriverMgr.cpp new file mode 100644 index 000000000000..b5cb7d4b5151 --- /dev/null +++ b/tools/lldb-mi/MIDriverMgr.cpp @@ -0,0 +1,762 @@ +//===-- MIDriverMgr.cpp -----------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +//++ +// File: MIDriverMgr.cpp +// +// Overview: CMIDriverMgr 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/SBError.h> + +// In-house headers: +#include "MIDriverMgr.h" +#include "MICmnResources.h" +#include "MICmnLog.h" +#include "MICmnLogMediumFile.h" +#include "MIDriver.h" +#include "MIUtilTermios.h" +#include "MICmnStreamStdout.h" +#include "MIUtilSingletonHelper.h" + +//++ ------------------------------------------------------------------------------------ +// Details: CMIDriverMgr constructor. +// Type: Method. +// Args: None. +// Return: None. +// Throws: None. +//-- +CMIDriverMgr::CMIDriverMgr( void ) +: m_pDriverCurrent( nullptr ) +, m_bInMi2Mode( false ) +{ +} + +//++ ------------------------------------------------------------------------------------ +// Details: CMIDriverMgr destructor. +// Type: Overridden. +// Args: None. +// Return: None. +// Throws: None. +//-- +CMIDriverMgr::~CMIDriverMgr( void ) +{ + Shutdown(); +} + +//++ ------------------------------------------------------------------------------------ +// Details: Initialize *this manager. +// Type: Method. +// Args: None. +// Return: MIstatus::success - Functional succeeded. +// MIstatus::failure - Functional failed. +// Throws: None. +//-- +bool CMIDriverMgr::Initialize( void ) +{ + m_clientUsageRefCnt++; + + ClrErrorDescription(); + + if( m_bInitialized ) + return MIstatus::success; + + bool bOk = MIstatus::success; + 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 ); + + if( bOk ) + { + MIUtilTermios::StdinTermiosSet(); + } + + m_bInitialized = bOk; + + if( !bOk ) + { + CMIUtilString strInitError( CMIUtilString::Format( MIRSRC( IDS_MI_INIT_ERR_DRIVERMGR ), errMsg.c_str() ) ); + SetErrorDescription( strInitError ); + return MIstatus::failure; + } + + return bOk; +} + +//++ ------------------------------------------------------------------------------------ +// Details: Unbind detach or release resources used by this server in general common +// functionality shared between versions of any server interfaces implemented. +// Type: Method. +// Args: vbAppExitOk - (R) True = No problems, false = App exiting with problems (investigate!). +// Return: MIstatus::success - Functional succeeded. +// MIstatus::failure - Functional failed. +// Throws: None. +//-- +bool CMIDriverMgr::Shutdown( void ) +{ + // Do not want a ref counter because this function needs to be called how ever this + // application stops running + //if( --m_clientUsageRefCnt > 0 ) + // return MIstatus::success; + + bool vbAppExitOk = true; + + ClrErrorDescription(); + + if( !m_bInitialized ) + return MIstatus::success; + + if( vbAppExitOk ) + { + // The MI Driver's log updating may have been switched off switch back on to say all is ok. + CMICmnLog::Instance().SetEnabled( true ); +#if _DEBUG + CMICmnStreamStdout::Instance().Write( MIRSRC( IDE_MI_APP_EXIT_OK ) ); // Both stdout and Log +#else + CMICmnLog::WriteLog( MIRSRC( IDE_MI_APP_EXIT_OK ) ); // Just to the Log +#endif // _DEBUG + } + else + { + CMICmnLog & rAppLog = CMICmnLog::Instance(); + if( rAppLog.GetEnabled() ) + { + const CMIUtilString msg( CMIUtilString::Format( MIRSRC( IDE_MI_APP_EXIT_WITH_PROBLEM ), CMICmnLogMediumFile::Instance().GetFileName().c_str() ) ); + CMICmnStreamStdout::Instance().Write( msg ); + } + else + { + // The MI Driver's log updating may have been switched off switch back on to say there has been problem. + rAppLog.SetEnabled( true ); + const CMIUtilString msg( CMIUtilString::Format( MIRSRC( IDE_MI_APP_EXIT_WITH_PROBLEM_NO_LOG ), CMICmnLogMediumFile::Instance().GetFileName().c_str() ) ); + CMICmnStreamStdout::Instance().Write( msg ); + } + } + + m_bInitialized = false; + + bool bOk = MIstatus::success; + CMIUtilString errMsg; + + // Tidy up + UnregisterDriverAll(); + MIUtilTermios::StdinTermiosReset(); + + // 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_SHTDWN_ERR_DRIVERMGR ), errMsg.c_str() ); + } + + return bOk; +} +//++ ------------------------------------------------------------------------------------ +// Details: Unregister all the Driver registered with *this manager. The manager also +// deletes +// Type: Method. +// Args: None. +// Return: MIstatus::success - Functional succeeded. +// MIstatus::failure - Functional failed. +// Throws: None. +//-- +bool CMIDriverMgr::UnregisterDriverAll( void ) +{ + MapDriverIdToDriver_t::const_iterator it = m_mapDriverIdToDriver.begin(); + while( it != m_mapDriverIdToDriver.end() ) + { + IDriver * pDriver = (*it).second; + pDriver->DoShutdown(); + + // Next + ++it; + } + + m_mapDriverIdToDriver.clear(); + m_pDriverCurrent = NULL; + + return MIstatus::success; +} + +//++ ------------------------------------------------------------------------------------ +// Details: Register a driver with *this Driver Manager. Call SetUseThisDriverToDoWork() +// inform the manager which driver is the one to the work. The manager calls +// the driver's init function which must be successful in order to complete the +// registration. +// Type: Method. +// Args: vrDriver - (R) The driver to register. +// vrDriverID - (R) The driver's ID to lookup by. +// Return: MIstatus::success - Functional succeeded. +// MIstatus::failure - Functional failed. +// Throws: None. +//-- +bool CMIDriverMgr::RegisterDriver( const IDriver & vrDriver, const CMIUtilString & vrDriverID ) +{ + if( HaveDriverAlready( vrDriver ) ) + return MIstatus::success; + + IDriver * pDriver = const_cast< IDriver * >( &vrDriver ); + if( !pDriver->SetId( vrDriverID ) ) + return MIstatus::failure; + if( !pDriver->DoInitialize() ) + { + SetErrorDescriptionn( MIRSRC( IDS_DRIVERMGR_DRIVER_ERR_INIT ), pDriver->GetName().c_str(), vrDriverID.c_str(), pDriver->GetError().c_str() ); + return MIstatus::failure; + } + + MapPairDriverIdToDriver_t pr( vrDriverID, pDriver ); + m_mapDriverIdToDriver.insert( pr ); + + return MIstatus::success; +} + +//++ ------------------------------------------------------------------------------------ +// Details: Query the Driver Manager to see if *this manager has the driver already +// registered. +// Type: Method. +// Args: vrDriver - (R) The driver to query. +// Return: True - registered. +// False - not registered. +// Throws: None. +//-- +bool CMIDriverMgr::HaveDriverAlready( const IDriver & vrDriver ) const +{ + MapDriverIdToDriver_t::const_iterator it = m_mapDriverIdToDriver.begin(); + while( it != m_mapDriverIdToDriver.end() ) + { + const IDriver * pDrvr = (*it).second; + if( pDrvr == &vrDriver ) + return true; + + // Next + ++it; + } + + return false; +} + +//++ ------------------------------------------------------------------------------------ +// Details: Unregister a driver from the Driver Manager. Call the SetUseThisDriverToDoWork() +// function to define another driver to do work if the one being unregistered did +// the work previously. +// Type: Method. +// Args: vrDriver - (R) The driver to unregister. +// Return: MIstatus::success - Functional succeeded. +// MIstatus::failure - Functional failed. +// Throws: None. +//-- +bool CMIDriverMgr::UnregisterDriver( const IDriver & vrDriver ) +{ + const IDriver * pDrvr = nullptr; + MapDriverIdToDriver_t::const_iterator it = m_mapDriverIdToDriver.begin(); + while( it != m_mapDriverIdToDriver.end() ) + { + pDrvr = (*it).second; + if( pDrvr == &vrDriver ) + break; + + // Next + ++it; + } + m_mapDriverIdToDriver.erase( it ); + + if( m_pDriverCurrent == pDrvr ) + m_pDriverCurrent = nullptr; + + return MIstatus::success; +} + +//++ ------------------------------------------------------------------------------------ +// Details: Specify the driver to do work. The Driver Manager drives this driver. Any +// previous driver doing work is not called anymore (so be sure the previous +// driver is in a tidy state before stopping it working). +// Type: Method. +// Args: vrADriver - (R) A lldb::SBBroadcaster/IDriver derived object. +// Return: MIstatus::success - Functional succeeded. +// MIstatus::failure - Functional failed. +// Throws: None. +//-- +bool CMIDriverMgr::SetUseThisDriverToDoWork( const IDriver & vrADriver ) +{ + m_pDriverCurrent = const_cast< IDriver * >( &vrADriver ); + + const CMIUtilString msg( CMIUtilString::Format( MIRSRC( IDS_DRIVER_SAY_DRIVER_USING ), m_pDriverCurrent->GetName().c_str() ) ); + m_pLog->Write( msg, CMICmnLog::eLogVerbosity_Log ); + + m_bInMi2Mode = m_pDriverCurrent->GetDriverIsGDBMICompatibleDriver(); + + return MIstatus::success; +} + +//++ ------------------------------------------------------------------------------------ +// Details: Ask *this manager which driver is currently doing the work. +// Type: Method. +// Args: None. +// Return: IDriver * - Pointer to a driver, NULL if there is no current working driver. +// Throws: None. +//-- +CMIDriverMgr::IDriver * CMIDriverMgr::GetUseThisDriverToDoWork( void ) const +{ + return m_pDriverCurrent; +} + +//++ ------------------------------------------------------------------------------------ +// Details: Call this function puts *this driver to work. +// Type: Method. +// Args: None. +// Return: MIstatus::success - Functional succeeded. +// MIstatus::failure - Functional failed. +// Throws: None. +//-- +bool CMIDriverMgr::DriverMainLoop( void ) +{ + if( m_pDriverCurrent != nullptr ) + { + if( !m_pDriverCurrent->DoMainLoop() ) + { + const CMIUtilString errMsg( CMIUtilString::Format( MIRSRC( IDS_DRIVER_ERR_MAINLOOP ), m_pDriverCurrent->GetError().c_str() ) ); + CMICmnStreamStdout::Instance().Write( errMsg, true ); + return MIstatus::failure; + } + } + else + { + const CMIUtilString errMsg( CMIUtilString::Format( MIRSRC( IDS_DRIVER_ERR_CURRENT_NOT_SET ) ) ); + CMICmnStreamStdout::Instance().Write( errMsg, true ); + return MIstatus::failure; + } + + return MIstatus::success; +} + +//++ ------------------------------------------------------------------------------------ +// Details: Call *this driver to resize the console window. +// Type: Method. +// Args: vWindowSizeWsCol - (R) New window column size. +// Return: MIstatus::success - Functional succeeded. +// MIstatus::failure - Functional failed. +// Throws: None. +//-- +void CMIDriverMgr::DriverResizeWindow( const uint32_t vWindowSizeWsCol ) +{ + if( m_pDriverCurrent != nullptr ) + return m_pDriverCurrent->DoResizeWindow( vWindowSizeWsCol ); + else + { + const CMIUtilString errMsg( CMIUtilString::Format( MIRSRC( IDS_DRIVER_ERR_CURRENT_NOT_SET ) ) ); + CMICmnStreamStdout::Instance().Write( errMsg, true ); + } +} + +//++ ------------------------------------------------------------------------------------ +// Details: Get the current driver to validate executable command line arguments. +// Type: Method. +// Args: argc - (R) An integer that contains the count of arguments that follow in +// argv. The argc parameter is always greater than or equal to 1. +// argv - (R) An array of null-terminated strings representing command-line +// arguments entered by the user of the program. By convention, +// argv[0] is the command with which the program is invoked. +// vpStdOut - (R) Point to a standard output stream. +// vwbExiting - (W) True = *this want to exit, false = continue to work. +// Return: MIstatus::success - Functional succeeded. +// MIstatus::failure - Functional failed. +// Throws: None. +//-- +bool CMIDriverMgr::DriverParseArgs( const int argc, const char * argv[], FILE * vpStdOut, bool & vwbExiting ) +{ + if( m_pDriverCurrent == nullptr ) + { + const CMIUtilString errMsg( CMIUtilString::Format( MIRSRC( IDS_DRIVER_ERR_CURRENT_NOT_SET ) ) ); + CMICmnStreamStdout::Instance().Write( errMsg, true ); + return MIstatus::failure; + } + + const lldb::SBError error( m_pDriverCurrent->DoParseArgs( argc, argv, vpStdOut, vwbExiting ) ); + bool bOk = !error.Fail(); + if( !bOk ) + { + CMIUtilString errMsg; + const MIchar * pErrorCstr = error.GetCString(); + if( pErrorCstr != nullptr ) + errMsg = CMIUtilString::Format( MIRSRC( IDS_DRIVER_ERR_PARSE_ARGS ), m_pDriverCurrent->GetName().c_str(), pErrorCstr ); + else + errMsg = CMIUtilString::Format( MIRSRC( IDS_DRIVER_ERR_PARSE_ARGS_UNKNOWN ), m_pDriverCurrent->GetName().c_str() ); + + bOk = CMICmnStreamStdout::Instance().Write( errMsg, true ); + } + + return bOk; +} + +//++ ------------------------------------------------------------------------------------ +// Details: Retrieve the current driver's last error condition. +// Type: Method. +// Args: None. +// Return: CMIUtilString - Text description. +// Throws: None. +//-- +CMIUtilString CMIDriverMgr::DriverGetError( void ) const +{ + if( m_pDriverCurrent != nullptr ) + return m_pDriverCurrent->GetError(); + else + { + const CMIUtilString errMsg( CMIUtilString::Format( MIRSRC( IDS_DRIVER_ERR_CURRENT_NOT_SET ) ) ); + CMICmnStreamStdout::Instance().Write( errMsg, true ); + } + + return CMIUtilString(); +} + +//++ ------------------------------------------------------------------------------------ +// Details: Retrieve the current driver's name. +// Type: Method. +// Args: None. +// Return: CMIUtilString - Driver name. +// Empty string = no current working driver specified. +// Throws: None. +//-- +CMIUtilString CMIDriverMgr::DriverGetName( void ) const +{ + if( m_pDriverCurrent != nullptr ) + return m_pDriverCurrent->GetName(); + else + { + const CMIUtilString errMsg( CMIUtilString::Format( MIRSRC( IDS_DRIVER_ERR_CURRENT_NOT_SET ) ) ); + CMICmnStreamStdout::Instance().Write( errMsg, true ); + } + + return CMIUtilString(); +} + +//++ ------------------------------------------------------------------------------------ +// Details: Retrieve the current driver's debugger object. +// Type: Method. +// Args: None. +// Return: lldb::SBDebugger * - Ptr to driver's debugger object. +// - NULL = no current working driver specified. +// Throws: None. +//-- +lldb::SBDebugger * CMIDriverMgr::DriverGetTheDebugger( void ) +{ + lldb::SBDebugger * pDebugger = nullptr; + if( m_pDriverCurrent != nullptr ) + pDebugger = &m_pDriverCurrent->GetTheDebugger(); + else + { + const CMIUtilString errMsg( CMIUtilString::Format( MIRSRC( IDS_DRIVER_ERR_CURRENT_NOT_SET ) ) ); + CMICmnStreamStdout::Instance().Write( errMsg, true ); + } + + return pDebugger; +} + +//++ ------------------------------------------------------------------------------------ +// Details: Check the arguments given on the command line. The main purpose of this +// function is to check for the presence of the --interpreter option. Having +// this option present tells *this manager to set the CMIDriver to do work. If +// not use the LLDB driver. The following are options that are only handled by +// the CMIDriverMgr are: +// --help or -h +// --interpreter +// --version +// --versionLong +// --noLog +// --executable +// The above arguments are not handled by any driver object except for --executable. +// The options --interpreter and --executable in code act very similar. The +// --executable is necessary to differentiate whither the MI Driver is being using +// by a client i.e. Eclipse or from the command line. Eclipse issues the option +// --interpreter and also passes additional arguments which can be interpreted as an +// executable if called from the command line. Using --executable tells the MI +// Driver is being called the command line and that the executable argument is indeed +// a specified executable an so actions commands to set up the executable for a +// debug session. Using --interpreter on the commnd line does not action additional +// commands to initialise a debug session and so be able to launch the process. +// Type: Method. +// Args: argc - (R) An integer that contains the count of arguments that follow in +// argv. The argc parameter is always greater than or equal to 1. +// argv - (R) An array of null-terminated strings representing command-line +// arguments entered by the user of the program. By convention, +// argv[0] is the command with which the program is invoked. +// vwbExiting - (W) True = *this want to exit, Reasons: help, invalid arg(s), +// version information only. +// False = Continue to work, start debugger i.e. Command +// interpreter. +// Return: lldb::SBError - LLDB current error status. +// Throws: None. +//-- +bool CMIDriverMgr::ParseArgs( const int argc, const char * argv[], bool & vwbExiting ) +{ + bool bOk = MIstatus::success; + + vwbExiting = false; + + // Print MI application path to the Log file + const CMIUtilString appPath( CMIUtilString::Format( MIRSRC( IDS_MI_APP_FILEPATHNAME ), argv[ 0 ] ) ); + bOk = m_pLog->Write( appPath, CMICmnLog::eLogVerbosity_Log ); + + // Print application arguments to the Log file + const bool bHaveArgs( argc >= 2 ); + CMIUtilString strArgs( MIRSRC( IDS_MI_APP_ARGS ) ); + if( !bHaveArgs ) + { + strArgs += MIRSRC( IDS_WORD_NONE ); + bOk = bOk && m_pLog->Write( strArgs, CMICmnLog::eLogVerbosity_Log ); + } + else + { + for( MIint i = 1; i < argc; i++ ) + { + strArgs += CMIUtilString::Format( "%d:'%s' ", i, argv[ i ] ); + } + bOk = bOk && m_pLog->Write( strArgs, CMICmnLog::eLogVerbosity_Log ); + } + + // Look for the command line options + bool bHaveArgInterpret = false; + bool bHaveArgVersion = false; + bool bHaveArgVersionLong = false; + bool bHaveArgNoLog = false; + bool bHaveArgHelp = false; + + // Hardcode the use of the MI driver +#if MICONFIG_DEFAULT_TO_MI_DRIVER + bHaveArgInterpret = true; +#endif // MICONFIG_DEFAULT_TO_MI_DRIVER + + if( bHaveArgs ) + { + // CODETAG_MIDRIVE_CMD_LINE_ARG_HANDLING + for( MIint i = 1; i < argc; i++ ) + { + // *** Add args to help in GetHelpOnCmdLineArgOptions() *** + const CMIUtilString strArg( argv[ i ] ); + + // Argument "--executable" is also check for in CMIDriver::ParseArgs() + if( (0 == strArg.compare( "--interpreter" )) || // Given by the client such as Eclipse + (0 == strArg.compare( "--executable" )) ) // Used to specify that there is executable argument also on the command line + { // See fn description. + bHaveArgInterpret = true; + } + if( 0 == strArg.compare( "--version" ) ) + { + bHaveArgVersion = true; + } + if( 0 == strArg.compare( "--versionLong" ) ) + { + bHaveArgVersionLong = true; + } + if( 0 == strArg.compare( "--noLog" ) ) + { + bHaveArgNoLog = true; + } + if( (0 == strArg.compare( "--help" )) || (0 == strArg.compare( "-h" )) ) + { + bHaveArgHelp = true; + } + } + } + + if( bHaveArgNoLog ) + { + CMICmnLog::Instance().SetEnabled( false ); + } + + // Todo: Remove this output when MI is finished. It is temporary to persuade Ecllipse plugin to work. + // Eclipse reads this literally and will not work unless it gets this exact version text. + // Handle --version option (ignore the --interpreter option if present) + if( bHaveArgVersion ) + { + vwbExiting = true; + bOk = bOk && CMICmnStreamStdout::Instance().WriteMIResponse( MIRSRC( IDE_MI_VERSION_GDB ) ); + return bOk; + } + + // Todo: Make this the --version when the the above --version version is removed + // Handle --versionlong option (ignore the --interpreter option if present) + if( bHaveArgVersionLong ) + { + vwbExiting = true; + bOk = bOk && CMICmnStreamStdout::Instance().WriteMIResponse( GetAppVersion() ); + return bOk; + } + + // Both '--help' and '--intepreter' means give help for MI only. Without + // '--interpreter' help the LLDB driver is working and so help is for that. + if( bHaveArgHelp && bHaveArgInterpret ) + { + vwbExiting = true; + bOk = bOk && CMICmnStreamStdout::Instance().WriteMIResponse( GetHelpOnCmdLineArgOptions() ); + return bOk; + } + + // This makes the assumption that there is at least one MI compatible + // driver registered and one LLDB driver registerd and the CMIDriver + // is the first one found. + // ToDo: Implement a better solution that handle any order, any number + // of drivers. Or this 'feature' may be removed if deemed not required. + IDriver * pLldbDriver = GetFirstNonMIDriver(); + IDriver * pMi2Driver = GetFirstMIDriver(); + if( bHaveArgInterpret && (pMi2Driver != nullptr) ) + bOk = bOk && SetUseThisDriverToDoWork( *pMi2Driver ); + else if( pLldbDriver != nullptr ) + bOk = bOk && SetUseThisDriverToDoWork( *pLldbDriver ); + else + { + if( bOk ) + { + vwbExiting = true; + const CMIUtilString msg( MIRSRC( IDS_DRIVER_ERR_NON_REGISTERED ) ); + bOk = bOk && CMICmnStreamStdout::Instance().WriteMIResponse( msg ); + } + } + + return bOk; +} + +//++ ------------------------------------------------------------------------------------ +// Details: Return formatted application version and name information. +// Type: Method. +// Args: None. +// Return: CMIUtilString - Text data. +// Throws: None. +//-- +CMIUtilString CMIDriverMgr::GetAppVersion( void ) const +{ + const CMIUtilString strProj( MIRSRC( IDS_PROJNAME ) ); + const CMIUtilString strVsn( CMIDriver::Instance().GetVersionDescription() ); + const CMIUtilString strGdb( MIRSRC( IDE_MI_VERSION_GDB ) ); + const CMIUtilString strVrsnInfo( CMIUtilString::Format( "%s\n%s\n%s", strProj.c_str(), strVsn.c_str(), strGdb.c_str() ) ); + + return strVrsnInfo; +} + +//++ ------------------------------------------------------------------------------------ +// Details: Return formatted help information on all the MI command line options. +// Type: Method. +// Args: None. +// Return: CMIUtilString - Text data. +// Throws: None. +//-- +CMIUtilString CMIDriverMgr::GetHelpOnCmdLineArgOptions( void ) const +{ + const CMIUtilString pHelp[] = + { + MIRSRC( IDE_MI_APP_DESCRIPTION ), + MIRSRC( IDE_MI_APP_INFORMATION ), + MIRSRC( IDE_MI_APP_ARG_USAGE ), + MIRSRC( IDE_MI_APP_ARG_HELP ), + MIRSRC( IDE_MI_APP_ARG_VERSION ), + MIRSRC( IDE_MI_APP_ARG_VERSION_LONG ), + MIRSRC( IDE_MI_APP_ARG_INTERPRETER ), + MIRSRC( IDE_MI_APP_ARG_EXECUTEABLE ), + CMIUtilString::Format( MIRSRC( IDE_MI_APP_ARG_NO_APP_LOG ), CMICmnLogMediumFile::Instance().GetFileName().c_str() ), + MIRSRC( IDE_MI_APP_ARG_EXECUTABLE ), + MIRSRC( IDS_CMD_QUIT_HELP ), + MIRSRC( IDE_MI_APP_ARG_EXAMPLE ) + }; + const MIuint nHelpItems = sizeof pHelp / sizeof pHelp[ 0 ]; + CMIUtilString strHelp; + for( MIuint i = 0; i < nHelpItems; i++ ) + { + strHelp += pHelp[ i ]; + strHelp += "\n\n"; + } + + return strHelp; +} + +//++ ------------------------------------------------------------------------------------ +// Details: Search the registered drivers and return the first driver which says it is +// GDB/MI compatible i.e. the CMIDriver class. +// Type: Method. +// Args: None. +// Return: IDriver * - Ptr to driver, NULL = no driver found. +// Throws: None. +//-- +CMIDriverMgr::IDriver * CMIDriverMgr::GetFirstMIDriver( void ) const +{ + IDriver * pDriver = nullptr; + MapDriverIdToDriver_t::const_iterator it = m_mapDriverIdToDriver.begin(); + while( it != m_mapDriverIdToDriver.end() ) + { + const CMIUtilString & rDrvId = (*it).first; MIunused( rDrvId ); + IDriver * pDvr = (*it).second; + if( pDvr->GetDriverIsGDBMICompatibleDriver() ) + { + pDriver = pDvr; + break; + } + + // Next + ++it; + } + + return pDriver; +} + +//++ ------------------------------------------------------------------------------------ +// Details: Search the registered drivers and return the first driver which says it is +// not GDB/MI compatible i.e. the LLDB Driver class. +// Type: Method. +// Args: None. +// Return: IDriver * - Ptr to driver, NULL = no driver found. +// Throws: None. +//-- +CMIDriverMgr::IDriver * CMIDriverMgr::GetFirstNonMIDriver( void ) const +{ + IDriver * pDriver = nullptr; + MapDriverIdToDriver_t::const_iterator it = m_mapDriverIdToDriver.begin(); + while( it != m_mapDriverIdToDriver.end() ) + { + const CMIUtilString & rDrvId = (*it).first; MIunused( rDrvId ); + IDriver * pDvr = (*it).second; + if( !pDvr->GetDriverIsGDBMICompatibleDriver() ) + { + pDriver = pDvr; + break; + } + + // Next + ++it; + } + + return pDriver; +} + +//++ ------------------------------------------------------------------------------------ +// Details: Search the registered drivers and return driver with the specified ID. +// Type: Method. +// Args: vrDriverId - (R) ID of a driver. +// Return: IDriver * - Ptr to driver, NULL = no driver found. +// Throws: None. +//-- +CMIDriverMgr::IDriver * CMIDriverMgr::GetDriver( const CMIUtilString & vrDriverId ) const +{ + MapDriverIdToDriver_t::const_iterator it = m_mapDriverIdToDriver.find( vrDriverId ); + if( it == m_mapDriverIdToDriver.end() ) + return nullptr; + + IDriver * pDriver = (*it).second; + + return pDriver; +} + |