aboutsummaryrefslogblamecommitdiff
path: root/tools/lldb-mi/MIDriver.cpp
blob: accde1c7cde728bcb1143fcfb65bc0efbc445b04 (plain) (tree)
1
2
3
4
5
6
7
8
9
10









                                                                                
                            
  
                                         
  


                                                                     
  
                     


                       
                                                 






















                                  
                                                                                            
     
                                                                                                                           
                

                                                                                  

                                                                                         




                                  
    









                                                     



                                                                                         




                                 
    
                           



                                                                                         







                                                                                     
    

                                              
 

                                            


                                                                                         






                                                                                     
    

                                        
 
                                           


                                                                                         




                                                     
    

                                      
 
                                


                                                                                         




                                                     
    

                                     
 
                               


                                                                                         




                                                        
    

                                            
 
                             


                                                                                         





                                                        
    

                           
 

                                                      
 
                          
 

                                 
 

                                 
 









                                                                                   

                                             












                                                                                                              

                                                   
                       
 
                         
 









                                                                                                        


                                                                                         





                                                                    
    

                         
 






























                                                                                       


                                                                                         






                                                                                         
    

                                                           
 


                                                                             



                                                                                         




                                                     
    

                             
 
                                              


                                                                                         






                                                                                       
    

                           
 
                                            


                                                                                         




                                               
    

                              
 




                                                                                               


                                                                                         




                                                         
    

                               
 
                                 


                                                                                         





                                                           
    

                                                    
 
                                                  


                                                                                         




                                                                
    

                               
 
                                            


                                                                                         






                                                                                        
    

                                                                    
 
                                                                    
 
                                                     


                                                                                         

















                                                                                              
    

                                                                                            
 
                                                       


                                                                                         

























                                                                                              
    

                                                                                          
 

































                                                                                                                                  
                                                                          
                                          
     

                                                                              
                                                                                
     
 
                     


                                                                                         





                                                                  
    

                                                       
 
                


                                                                                         









                                                                                              
    

                                                                         
 


                                                         
 



                                                                                  
 



                                                                                          
 


                                                                           
 
               


                                                                                         





                                                     
    

                                   
 
























                                                                                                                         


                                                                                         





                                                     
    

                                  
 

                                                                    


                                                                                         






                                                                   
    

                           
 












                                                                          
                                                                          







                                                                             

                                                                                









                                        
 

                                                   
 

                                             
 

                                                                         
 
                             


                                                                                         








                                                                                         
    

                                   
 











































                                                                  


                                                                                         







                                                                                 
    

                          
 
                         
 




                                              
 
                    


                                                                                         








                                                                                        
    

                                                                                               
 






























                                                                                                                                         


                                                                                         




                                               
    

                                    
 
                     


                                                                                         




                                               
    

                                  
 
                   


                                                                                         









                                                                                       
    

                                                                                        
 
                                 
 


                                                          
 
                                                                   


                                                                                         






                                                                                      
    

                               
 

                                                                                 
 


                                                                             


                                                                                         





                                                                                      
    

                                
 

                                                                                 
 

                                                            


                                                                                         





                                                                                            
    

                                
 

                                                                                 
 


                                                                                


                                                                                         





                                                                 
    

                                          
 







                                                                                                


                                                                                         




                                               
    

                            
 
                         


                                                                                         







                                                                                      
    

                                                       
 
                                                       
 
                                         


                                                                                         






                                                                                   
    

                                                      
 



                                          
 
 
                                                                                         









                                                                                      
    

                                                           
 



                                                                      
 
               


                                                                                         










                                                                                       
    

                                                                                           
 












































                                                                                                                               


                                                                                         







                                                                                     
    

                                                     
 

                                               


                                                                                         








                                                                                        
    

                                                         
 



















                                                                                  


                                                                                         





                                                                                      
    

                                             
 
                      


                                                                                         




                                                                           
    

                                            
 
                                 


                                                                                         






                                                                                          
    

                                                  
 

































                                                                                                                              


                                                                                         







                                                                                          
    

                                               
 
































                                                                                                                                           


                                                                                         






                                                                                       
    

                                              
 

                                        



                                                                                         






                                                                                      
    

                                           
 
                                      
 
                             


                                                                                         








                                                                                         
    

                                                          
 
                                                  



                                                                                         




                                                                         
    

                                                         
 
                                                  



                                                                                         






                                                                                   
    

                                                       
 


                                                                                                                                   



                                                                                         




                                                              
    

                                                
 
                                           


                                                                                         






                                                                                        
    

                                                     
 
                                           
 
//===-- MIDriver.cpp --------------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

//++
// File:        MIDriver.cpp
//
// Overview:    CMIDriver 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 <stdarg.h> // va_list, va_start, var_end
#include <iostream>
#include <lldb/API/SBError.h>

// In-house headers:
#include "Driver.h"
#include "MIDriver.h"
#include "MICmnResources.h"
#include "MICmnLog.h"
#include "MICmdMgr.h"
#include "MICmnLLDBDebugger.h"
#include "MICmnMIResultRecord.h"
#include "MICmnMIValueConst.h"
#include "MICmnThreadMgrStd.h"
#include "MIUtilDebug.h"
#include "MIUtilSingletonHelper.h"
#include "MICmnStreamStdout.h"
#include "MICmnStreamStderr.h"
#include "MICmdArgValFile.h"
#include "MICmdArgValString.h"
#include "MICmnConfig.h"

// Instantiations:
#if _DEBUG
const CMIUtilString CMIDriver::ms_constMIVersion = MIRSRC(IDS_MI_VERSION_DESCRIPTION_DEBUG);
#else
const CMIUtilString CMIDriver::ms_constMIVersion = MIRSRC(IDS_MI_VERSION_DESCRIPTION); // Matches version in resources file
#endif // _DEBUG
const CMIUtilString CMIDriver::ms_constAppNameShort(MIRSRC(IDS_MI_APPNAME_SHORT));
const CMIUtilString CMIDriver::ms_constAppNameLong(MIRSRC(IDS_MI_APPNAME_LONG));

//++ ------------------------------------------------------------------------------------
// Details: CMIDriver constructor.
// Type:    Method.
// Args:    None.
// Return:  None.
// Throws:  None.
//--
CMIDriver::CMIDriver(void)
    : m_bFallThruToOtherDriverEnabled(false)
    , m_bDriverIsExiting(false)
    , m_handleMainThread(0)
    , m_rStdin(CMICmnStreamStdin::Instance())
    , m_rLldbDebugger(CMICmnLLDBDebugger::Instance())
    , m_rStdOut(CMICmnStreamStdout::Instance())
    , m_eCurrentDriverState(eDriverState_NotRunning)
    , m_bHaveExecutableFileNamePathOnCmdLine(false)
    , m_bDriverDebuggingArgExecutable(false)
{
}

//++ ------------------------------------------------------------------------------------
// Details: CMIDriver destructor.
// Type:    Overridden.
// Args:    None.
// Return:  None.
// Throws:  None.
//--
CMIDriver::~CMIDriver(void)
{
}

//++ ------------------------------------------------------------------------------------
// Details: Set whether *this driver (the parent) is enabled to pass a command to its
//          fall through (child) driver to interpret the command and do work instead
//          (if *this driver decides it can't hanled the command).
// Type:    Method.
// Args:    vbYes   - (R) True = yes fall through, false = do not pass on command.
// Return:  MIstatus::success - Functional succeeded.
//          MIstatus::failure - Functional failed.
// Throws:  None.
//--
bool
CMIDriver::SetEnableFallThru(const bool vbYes)
{
    m_bFallThruToOtherDriverEnabled = vbYes;
    return MIstatus::success;
}

//++ ------------------------------------------------------------------------------------
// Details: Get whether *this driver (the parent) is enabled to pass a command to its
//          fall through (child) driver to interpret the command and do work instead
//          (if *this driver decides it can't hanled the command).
// Type:    Method.
// Args:    None.
// Return:  bool - True = yes fall through, false = do not pass on command.
// Throws:  None.
//--
bool
CMIDriver::GetEnableFallThru(void) const
{
    return m_bFallThruToOtherDriverEnabled;
}

//++ ------------------------------------------------------------------------------------
// Details: Retrieve MI's application name of itself.
// Type:    Method.
// Args:    None.
// Return:  CMIUtilString & - Text description.
// Throws:  None.
//--
const CMIUtilString &
CMIDriver::GetAppNameShort(void) const
{
    return ms_constAppNameShort;
}

//++ ------------------------------------------------------------------------------------
// Details: Retrieve MI's application name of itself.
// Type:    Method.
// Args:    None.
// Return:  CMIUtilString & - Text description.
// Throws:  None.
//--
const CMIUtilString &
CMIDriver::GetAppNameLong(void) const
{
    return ms_constAppNameLong;
}

//++ ------------------------------------------------------------------------------------
// Details: Retrieve MI's version description of itself.
// Type:    Method.
// Args:    None.
// Return:  CMIUtilString & - Text description.
// Throws:  None.
//--
const CMIUtilString &
CMIDriver::GetVersionDescription(void) const
{
    return ms_constMIVersion;
}

//++ ------------------------------------------------------------------------------------
// 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;

    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;
}

//++ ------------------------------------------------------------------------------------
// 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;
}

//++ ------------------------------------------------------------------------------------
// Details: Work function. Client (the driver's user) is able to append their own message
//          in to the MI's Log trace file.
// Type:    Method.
// Args:    vMessage          - (R) Client's text message.
// Return:  MIstatus::success - Functional succeeded.
//          MIstatus::failure - Functional failed.
// Throws:  None.
//--
bool
CMIDriver::WriteMessageToLog(const CMIUtilString &vMessage)
{
    CMIUtilString msg;
    msg = CMIUtilString::Format(MIRSRC(IDS_MI_CLIENT_MSG), vMessage.c_str());
    return m_pLog->Write(msg, CMICmnLog::eLogVerbosity_ClientMsg);
}

//++ ------------------------------------------------------------------------------------
// Details: CDriverMgr calls *this driver initialize setup ready for use.
// Type:    Overridden.
// Args:    None.
// Return:  MIstatus::success - Functional succeeded.
//          MIstatus::failure - Functional failed.
// Throws:  None.
//--
bool
CMIDriver::DoInitialize(void)
{
    return CMIDriver::Instance().Initialize();
}

//++ ------------------------------------------------------------------------------------
// Details: CDriverMgr calls *this driver to unbind detach or release resources used by
//          *this driver.
// Type:    Overridden.
// Args:    None.
// Return:  MIstatus::success - Functional succeeded.
//          MIstatus::failure - Functional failed.
// Throws:  None.
//--
bool
CMIDriver::DoShutdown(void)
{
    return CMIDriver::Instance().Shutdown();
}

//++ ------------------------------------------------------------------------------------
// Details: Retrieve the name for *this driver.
// Type:    Overridden.
// Args:    None.
// Return:  CMIUtilString & - Driver name.
// Throws:  None.
//--
const CMIUtilString &
CMIDriver::GetName(void) const
{
    const CMIUtilString &rName = GetAppNameLong();
    const CMIUtilString &rVsn = GetVersionDescription();
    static CMIUtilString strName = CMIUtilString::Format("%s %s", rName.c_str(), rVsn.c_str());

    return strName;
}

//++ ------------------------------------------------------------------------------------
// Details: Retrieve *this driver's last error condition.
// Type:    Overridden.
// Args:    None.
// Return:  CMIUtilString - Text description.
// Throws:  None.
//--
CMIUtilString
CMIDriver::GetError(void) const
{
    return GetErrorDescription();
}

//++ ------------------------------------------------------------------------------------
// Details: Call *this driver to resize the console window.
// Type:    Overridden.
// Args:    vTermWidth - (R) New window column size.
// Return:  MIstatus::success - Functional succeeded.
//          MIstatus::failure - Functional failed.
// Throws:  None.
//--
void
CMIDriver::DoResizeWindow(const uint32_t vTermWidth)
{
    GetTheDebugger().SetTerminalWidth(vTermWidth);
}

//++ ------------------------------------------------------------------------------------
// Details: Call *this driver to return it's debugger.
// Type:    Overridden.
// Args:    None.
// Return:  lldb::SBDebugger & - LLDB debugger object reference.
// Throws:  None.
//--
lldb::SBDebugger &
CMIDriver::GetTheDebugger(void)
{
    return m_rLldbDebugger.GetTheDebugger();
}

//++ ------------------------------------------------------------------------------------
// Details: Specify another driver *this driver can call should this driver not be able
//          to handle the client data input. DoFallThruToAnotherDriver() makes the call.
// Type:    Overridden.
// Args:    vrOtherDriver     - (R) Reference to another driver object.
// Return:  MIstatus::success - Functional succeeded.
//          MIstatus::failure - Functional failed.
// Throws:  None.
//--
bool
CMIDriver::SetDriverToFallThruTo(const CMIDriverBase &vrOtherDriver)
{
    m_pDriverFallThru = const_cast<CMIDriverBase *>(&vrOtherDriver);

    return m_pDriverFallThru->SetDriverParent(*this);
}

//++ ------------------------------------------------------------------------------------
// Details: Proxy function CMIDriverMgr IDriver interface implementation. *this driver's
//          implementation called from here to match the existing function name of the
//          original LLDb driver class (the extra indirection is not necessarily required).
//          Check the arguments that were passed to this program to make sure they are
//          valid and to get their argument values (if any).
// Type:    Overridden.
// 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)   Pointer to a standard output stream.
//          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.
//--
lldb::SBError
CMIDriver::DoParseArgs(const int argc, const char *argv[], FILE *vpStdOut, bool &vwbExiting)
{
    return ParseArgs(argc, argv, vpStdOut, vwbExiting);
}

//++ ------------------------------------------------------------------------------------
// Details: Check the arguments that were passed to this program to make sure they are
//          valid and to get their argument values (if any). The following are options
//          that are only handled by *this driver:
//              --executable
//          The application's 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:    Overridden.
// 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)   Pointer to a standard output stream.
//          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.
//--
lldb::SBError
CMIDriver::ParseArgs(const int argc, const char *argv[], FILE *vpStdOut, bool &vwbExiting)
{
    lldb::SBError errStatus;
    const bool bHaveArgs(argc >= 2);

    // *** Add any args handled here to GetHelpOnCmdLineArgOptions() ***

    // CODETAG_MIDRIVE_CMD_LINE_ARG_HANDLING
    // Look for the command line options
    bool bHaveExecutableFileNamePath = false;
    bool bHaveExecutableLongOption = false;

    if (bHaveArgs)
    {
        // Search right to left to look for the executable
        for (MIint i = argc - 1; i > 0; i--)
        {
            const CMIUtilString strArg(argv[i]);
            const CMICmdArgValFile argFile;
            if (argFile.IsFilePath(strArg) || CMICmdArgValString(true, false, true).IsStringArg(strArg))
            {
                bHaveExecutableFileNamePath = true;
                m_strCmdLineArgExecuteableFileNamePath = argFile.GetFileNamePath(strArg);
                m_bHaveExecutableFileNamePathOnCmdLine = true;
            }
            // This argument is also check for in CMIDriverMgr::ParseArgs()
            if (0 == strArg.compare("--executable")) // Used to specify that there is executable argument also on the command line
            {                                        // See fn description.
                bHaveExecutableLongOption = true;
            }
        }
    }

    if (bHaveExecutableFileNamePath && bHaveExecutableLongOption)
    {
// CODETAG_CMDLINE_ARG_EXECUTABLE_DEBUG_SESSION
#if MICONFIG_ENABLE_MI_DRIVER_MI_MODE_CMDLINE_ARG_EXECUTABLE_DEBUG_SESSION
        SetDriverDebuggingArgExecutable();
#else
        vwbExiting = true;
        errStatus.SetErrorString(MIRSRC(IDS_DRIVER_ERR_LOCAL_DEBUG_NOT_IMPL));
#endif // MICONFIG_ENABLE_MI_DRIVER_MI_MODE_CMDLINE_ARG_EXECUTABLE_DEBUG_SESSION
    }

    return errStatus;
}

//++ ------------------------------------------------------------------------------------
// Details: A client can ask if *this driver is GDB/MI compatible.
// Type:    Overridden.
// Args:    None.
// Return:  True - GBD/MI compatible LLDB front end.
//          False - Not GBD/MI compatible LLDB front end.
// Throws:  None.
//--
bool
CMIDriver::GetDriverIsGDBMICompatibleDriver(void) const
{
    return true;
}

//++ ------------------------------------------------------------------------------------
// Details: Callback function for monitoring stream stdin object. Part of the visitor
//          pattern.
//          This function is called by the CMICmnStreamStdin::CThreadStdin
//          "stdin monitor" thread (ID).
// Type:    Overridden.
// Args:    vStdInBuffer    - (R) Copy of the current stdin line data.
//          vrbYesExit      - (RW) True = yes exit stdin monitoring, false = continue monitor.
// Return:  MIstatus::success - Functional succeeded.
//          MIstatus::failure - Functional failed.
// Throws:  None.
//--
bool
CMIDriver::ReadLine(const CMIUtilString &vStdInBuffer, bool &vrwbYesExit)
{
    // For debugging. Update prompt show stdin is working
    // printf( "%s\n", vStdInBuffer.c_str() );
    // fflush( stdout );

    // Special case look for the quit command here so stop monitoring stdin stream
    // So we do not go back to fgetc() and wait and hang thread on exit
    if (vStdInBuffer == "quit")
        vrwbYesExit = true;

    // 1. Put new line in the queue container by stdin monitor thread
    // 2. Then *this driver calls ReadStdinLineQueue() when ready to read the queue in its
    // own thread
    const bool bOk = QueueMICommand(vStdInBuffer);

    // Check to see if the *this driver is shutting down (exit application)
    if (!vrwbYesExit)
        vrwbYesExit = m_bDriverIsExiting;

    return bOk;
}

//++ ------------------------------------------------------------------------------------
// Details: Start worker threads for the driver.
// Type:    Method.
// Args:    None.
// Return:  MIstatus::success - Functional succeeded.
//          MIstatus::failure - Functional failed.
// Throws:  None.
//--
bool
CMIDriver::StartWorkerThreads(void)
{
    bool bOk = MIstatus::success;

    // Grab the thread manager
    CMICmnThreadMgrStd &rThreadMgr = CMICmnThreadMgrStd::Instance();

    // Start the stdin thread
    bOk &= m_rStdin.SetVisitor(*this);
    if (bOk && !rThreadMgr.ThreadStart<CMICmnStreamStdin>(m_rStdin))
    {
        const CMIUtilString errMsg = CMIUtilString::Format(MIRSRC(IDS_THREADMGR_ERR_THREAD_FAIL_CREATE),
                                                           CMICmnThreadMgrStd::Instance().GetErrorDescription().c_str());
        SetErrorDescriptionn(errMsg);
        return MIstatus::failure;
    }

    // Start the event polling thread
    if (bOk && !rThreadMgr.ThreadStart<CMICmnLLDBDebugger>(m_rLldbDebugger))
    {
        const CMIUtilString errMsg = CMIUtilString::Format(MIRSRC(IDS_THREADMGR_ERR_THREAD_FAIL_CREATE),
                                                           CMICmnThreadMgrStd::Instance().GetErrorDescription().c_str());
        SetErrorDescriptionn(errMsg);
        return MIstatus::failure;
    }

    return bOk;
}

//++ ------------------------------------------------------------------------------------
// Details: Stop worker threads for the driver.
// Type:    Method.
// Args:    None.
// Return:  MIstatus::success - Functional succeeded.
//          MIstatus::failure - Functional failed.
// Throws:  None.
//--
bool
CMIDriver::StopWorkerThreads(void)
{
    CMICmnThreadMgrStd &rThreadMgr = CMICmnThreadMgrStd::Instance();
    return rThreadMgr.ThreadAllTerminate();
}

//++ ------------------------------------------------------------------------------------
// Details: Call this function puts *this driver to work.
//          This function is used by the application's main thread.
// Type:    Overridden.
// Args:    None.
// Return:  MIstatus::success - Functional succeeded.
//          MIstatus::failure - Functional failed.
// Throws:  None.
//--
bool
CMIDriver::DoMainLoop(void)
{
    if (!InitClientIDEToMIDriver()) // Init Eclipse IDE
    {
        SetErrorDescriptionn(MIRSRC(IDS_MI_INIT_ERR_CLIENT_USING_DRIVER));
        return MIstatus::failure;
    }

    if (!StartWorkerThreads())
        return MIstatus::failure;

    // App is not quitting currently
    m_bExitApp = false;

// CODETAG_CMDLINE_ARG_EXECUTABLE_DEBUG_SESSION
#if MICONFIG_ENABLE_MI_DRIVER_MI_MODE_CMDLINE_ARG_EXECUTABLE_DEBUG_SESSION
    if (HaveExecutableFileNamePathOnCmdLine())
    {
        if (!LocalDebugSessionStartupInjectCommands())
        {
            SetErrorDescription(MIRSRC(IDS_MI_INIT_ERR_LOCAL_DEBUG_SESSION));
            return MIstatus::failure;
        }
    }
#endif // MICONFIG_ENABLE_MI_DRIVER_MI_MODE_CMDLINE_ARG_EXECUTABLE_DEBUG_SESSION

    // While the app is active
    while (!m_bExitApp)
    {
        // Poll stdin queue and dispatch
        if (!ReadStdinLineQueue())
        {
            // Something went wrong
            break;
        }
    }

    // Signal that the application is shutting down
    DoAppQuit();

    // Close and wait for the workers to stop
    StopWorkerThreads();

    // Ensure that a new line is sent as the last act of the dying driver
    m_rStdOut.WriteMIResponse("\n", false);

    return MIstatus::success;
}

//++ ------------------------------------------------------------------------------------
// 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;
}

//++ ------------------------------------------------------------------------------------
// Details: Set things in motion, set state etc that brings *this driver (and the
//          application) to a tidy shutdown.
//          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::DoAppQuit(void)
{
    bool bYesQuit = true;

    // Shutdown stuff, ready app for exit
    {
        CMIUtilThreadLock lock(m_threadMutex);
        m_bDriverIsExiting = true;
    }

    return bYesQuit;
}

//++ ------------------------------------------------------------------------------------
// Details: *this driver passes text commands to a fall through driver is it does not
//          understand them (the LLDB driver).
//          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 valid, false = command not handled.
// Return:  MIstatus::success - Functional succeeded.
//          MIstatus::failure - Functional failed.
// Throws:  None.
//--
bool
CMIDriver::InterpretCommandFallThruDriver(const CMIUtilString &vTextLine, bool &vwbCmdYesValid)
{
    MIunused(vTextLine);
    MIunused(vwbCmdYesValid);

    // ToDo: Implement when less urgent work to be done or decide remove as not required
    // bool bOk = MIstatus::success;
    // bool bCmdNotUnderstood = true;
    // if( bCmdNotUnderstood && GetEnableFallThru() )
    //{
    //  CMIUtilString errMsg;
    //  bOk = DoFallThruToAnotherDriver( vStdInBuffer, errMsg );
    //  if( !bOk )
    //  {
    //      errMsg = errMsg.StripCREndOfLine();
    //      errMsg = errMsg.StripCRAll();
    //      const CMIDriverBase * pOtherDriver = GetDriverToFallThruTo();
    //      const MIchar * pName = pOtherDriver->GetDriverName().c_str();
    //      const MIchar * pId = pOtherDriver->GetDriverId().c_str();
    //      const CMIUtilString msg( CMIUtilString::Format( MIRSRC( IDS_DRIVER_ERR_FALLTHRU_DRIVER_ERR ), pName, pId, errMsg.c_str() )
    //);
    //      m_pLog->WriteMsg( msg );
    //  }
    //}
    //
    // vwbCmdYesValid = bOk;
    // CMIUtilString strNot;
    // if( vwbCmdYesValid)
    //  strNot = CMIUtilString::Format( "%s ", MIRSRC( IDS_WORD_NOT ) );
    // const CMIUtilString msg( CMIUtilString::Format( MIRSRC( IDS_FALLTHRU_DRIVER_CMD_RECEIVED ), vTextLine.c_str(), strNot.c_str() ) );
    // m_pLog->WriteLog( msg );

    return MIstatus::success;
}

//++ ------------------------------------------------------------------------------------
// Details: Retrieve the name for *this driver.
// Type:    Overridden.
// Args:    None.
// Return:  CMIUtilString & - Driver name.
// Throws:  None.
//--
const CMIUtilString &
CMIDriver::GetDriverName(void) const
{
    return GetName();
}

//++ ------------------------------------------------------------------------------------
// Details: Get the unique ID for *this driver.
// Type:    Overridden.
// Args:    None.
// Return:  CMIUtilString & - Text description.
// Throws:  None.
//--
const CMIUtilString &
CMIDriver::GetDriverId(void) const
{
    return GetId();
}

//++ ------------------------------------------------------------------------------------
// 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
CMIDriver::DoFallThruToAnotherDriver(const CMIUtilString &vCmd, CMIUtilString &vwErrMsg)
{
    bool bOk = MIstatus::success;

    CMIDriverBase *pOtherDriver = GetDriverToFallThruTo();
    if (pOtherDriver == nullptr)
        return bOk;

    return pOtherDriver->DoFallThruToAnotherDriver(vCmd, vwErrMsg);
}

//++ ------------------------------------------------------------------------------------
// Details: *this driver provides a file stream to other drivers on which *this driver
//          write's out to and they read as expected input. *this driver is passing
//          through commands to the (child) pass through assigned driver.
// Type:    Overrdidden.
// Args:    None.
// Return:  FILE * - Pointer to stream.
// Throws:  None.
//--
FILE *
CMIDriver::GetStdin(void) const
{
    // Note this fn is called on CMIDriverMgr register driver so stream has to be
    // available before *this driver has been initialized! Flaw?

    // This very likely to change later to a stream that the pass thru driver
    // will read and we write to give it 'input'
    return stdin;
}

//++ ------------------------------------------------------------------------------------
// Details: *this driver provides a file stream to other pass through assigned drivers
//          so they know what to write to.
// Type:    Overidden.
// Args:    None.
// Return:  FILE * - Pointer to stream.
// Throws:  None.
//--
FILE *
CMIDriver::GetStdout(void) const
{
    // Note this fn is called on CMIDriverMgr register driver so stream has to be
    // available before *this driver has been initialized! Flaw?

    // Do not want to pass through driver to write to stdout
    return NULL;
}

//++ ------------------------------------------------------------------------------------
// Details: *this driver provides a error file stream to other pass through assigned drivers
//          so they know what to write to.
// Type:    Overidden.
// Args:    None.
// Return:  FILE * - Pointer to stream.
// Throws:  None.
//--
FILE *
CMIDriver::GetStderr(void) const
{
    // Note this fn is called on CMIDriverMgr register driver so stream has to be
    // available before *this driver has been initialized! Flaw?

    // This very likely to change later to a stream that the pass thru driver
    // will write to and *this driver reads from to pass on the CMICmnLog object
    return stderr;
}

//++ ------------------------------------------------------------------------------------
// 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;
}

//++ ------------------------------------------------------------------------------------
// Details: Get the unique ID for *this driver.
// Type:    Overridden.
// Args:    None.
// Return:  CMIUtilString & - Text description.
// Throws:  None.
//--
const CMIUtilString &
CMIDriver::GetId(void) const
{
    return m_strDriverId;
}

//++ ------------------------------------------------------------------------------------
// Details: Inject a command into the command processing system to be interpreted as a
//          command read from stdin. The text representing the command is also written
//          out to stdout as the command did not come from via stdin.
// Type:    Method.
// Args:    vMICmd  - (R) Text data representing a possible command.
// Return:  MIstatus::success - Functional succeeded.
//          MIstatus::failure - Functional failed.
// Throws:  None.
//--
bool
CMIDriver::InjectMICommand(const CMIUtilString &vMICmd)
{
    const bool bOk = m_rStdOut.WriteMIResponse(vMICmd);

    return bOk && QueueMICommand(vMICmd);
}

//++ ------------------------------------------------------------------------------------
// Details: Add a new command candidate to the command queue to be processed by the
//          command system.
// Type:    Method.
// Args:    vMICmd  - (R) Text data representing a possible command.
// Return:  MIstatus::success - Functional succeeded.
//          MIstatus::failure - Functional failed.
// Throws:  None.
//--
bool
CMIDriver::QueueMICommand(const CMIUtilString &vMICmd)
{
    CMIUtilThreadLock lock(m_threadMutex);
    m_queueStdinLine.push(vMICmd);

    return MIstatus::success;
}

//++ ------------------------------------------------------------------------------------
// 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. The
//          text data if not understood by *this driver is past on to the Fall Thru
//          driver.
//          This function is used by the application's main thread.
// Type:    Method.
// Args:    vTextLine   - (R) Text data representing a possible command.
// Return:  MIstatus::success - Functional succeeded.
//          MIstatus::failure - Functional failed.
// Throws:  None.
//--
bool
CMIDriver::InterpretCommand(const CMIUtilString &vTextLine)
{
    bool bCmdYesValid = false;
    bool bOk = InterpretCommandThisDriver(vTextLine, bCmdYesValid);
    if (bOk && !bCmdYesValid)
        bOk = InterpretCommandFallThruDriver(vTextLine, bCmdYesValid);

    return bOk;
}

//++ ------------------------------------------------------------------------------------
// 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);
    }

    // Check for escape character, may be cursor control characters
    // This code is not necessary for application operation, just want to keep tabs on what
    // is been given to the driver to try and intepret.
    if (vTextLine.at(0) == 27)
    {
        CMIUtilString logInput(MIRSRC(IDS_STDIN_INPUT_CTRL_CHARS));
        for (MIuint i = 0; i < vTextLine.length(); i++)
        {
            logInput += CMIUtilString::Format("%d ", vTextLine.at(i));
        }
        m_pLog->WriteLog(logInput);
        return MIstatus::success;
    }

    // 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: Having previously had the potential command validated and found valid now
//          get the command executed.
//          This function is used by the application's main thread.
// Type:    Method.
// Args:    vCmdData    - (RW) Command meta data.
// Return:  MIstatus::success - Functional succeeded.
//          MIstatus::failure - Functional failed.
// Throws:  None.
//--
bool
CMIDriver::ExecuteCommand(const SMICmdData &vCmdData)
{
    CMICmdMgr &rCmdMgr = CMICmdMgr::Instance();
    return rCmdMgr.CmdExecute(vCmdData);
}

//++ ------------------------------------------------------------------------------------
// Details: Set the MI Driver's exit application flag. The application checks this flag
//          after every stdin line is read so the exit may not be instantaneous.
//          If vbForceExit is false the MI Driver queries its state and determines if is
//          should exit or continue operating depending on that running state.
//          This is related to the running state of the MI driver.
// Type:    Overridden.
// Args:    None.
// Return:  None.
// Throws:  None.
//--
void
CMIDriver::SetExitApplicationFlag(const bool vbForceExit)
{
    if (vbForceExit)
    {
        CMIUtilThreadLock lock(m_threadMutex);
        m_bExitApp = true;
        m_rStdin.OnExitHandler();
        return;
    }

    // CODETAG_DEBUG_SESSION_RUNNING_PROG_RECEIVED_SIGINT_PAUSE_PROGRAM
    // Did we receive a SIGINT from the client during a running debug program, if
    // so then SIGINT is not to be taken as meaning kill the MI driver application
    // but halt the inferior program being debugged instead
    if (m_eCurrentDriverState == eDriverState_RunningDebugging)
    {
        InjectMICommand("-exec-interrupt");
        return;
    }

    m_bExitApp = true;
    m_rStdin.OnExitHandler();
}

//++ ------------------------------------------------------------------------------------
// Details: Get the  MI Driver's exit exit application flag.
//          This is related to the running state of the MI driver.
// Type:    Method.
// Args:    None.
// Return:  bool    - True = MI Driver is shutting down, false = MI driver is running.
// Throws:  None.
//--
bool
CMIDriver::GetExitApplicationFlag(void) const
{
    return m_bExitApp;
}

//++ ------------------------------------------------------------------------------------
// Details: Get the current running state of the MI Driver.
// Type:    Method.
// Args:    None.
// Return:  DriverState_e   - The current running state of the application.
// Throws:  None.
//--
CMIDriver::DriverState_e
CMIDriver::GetCurrentDriverState(void) const
{
    return m_eCurrentDriverState;
}

//++ ------------------------------------------------------------------------------------
// Details: Set the current running state of the MI Driver to running and currently not in
//          a debug session.
// Type:    Method.
// Return:  MIstatus::success - Functionality succeeded.
//          MIstatus::failure - Functionality failed.
// Return:  DriverState_e   - The current running state of the application.
// Throws:  None.
//--
bool
CMIDriver::SetDriverStateRunningNotDebugging(void)
{
    // CODETAG_DEBUG_SESSION_RUNNING_PROG_RECEIVED_SIGINT_PAUSE_PROGRAM

    if (m_eCurrentDriverState == eDriverState_RunningNotDebugging)
        return MIstatus::success;

    // Driver cannot be in the following states to set eDriverState_RunningNotDebugging
    switch (m_eCurrentDriverState)
    {
        case eDriverState_NotRunning:
        case eDriverState_Initialising:
        case eDriverState_ShuttingDown:
        {
            SetErrorDescription(MIRSRC(IDS_DRIVER_ERR_DRIVER_STATE_ERROR));
            return MIstatus::failure;
        }
        case eDriverState_RunningDebugging:
        case eDriverState_RunningNotDebugging:
            break;
        case eDriverState_count:
            SetErrorDescription(
                CMIUtilString::Format(MIRSRC(IDS_CODE_ERR_INVALID_ENUMERATION_VALUE), "SetDriverStateRunningNotDebugging()"));
            return MIstatus::failure;
    }

    // Driver must be in this state to set eDriverState_RunningNotDebugging
    if (m_eCurrentDriverState != eDriverState_RunningDebugging)
    {
        SetErrorDescription(MIRSRC(IDS_DRIVER_ERR_DRIVER_STATE_ERROR));
        return MIstatus::failure;
    }

    m_eCurrentDriverState = eDriverState_RunningNotDebugging;

    return MIstatus::success;
}

//++ ------------------------------------------------------------------------------------
// Details: Set the current running state of the MI Driver to running and currently not in
//          a debug session. The driver's state must in the state running and in a
//          debug session to set this new state.
// Type:    Method.
// Return:  MIstatus::success - Functionality succeeded.
//          MIstatus::failure - Functionality failed.
// Return:  DriverState_e   - The current running state of the application.
// Throws:  None.
//--
bool
CMIDriver::SetDriverStateRunningDebugging(void)
{
    // CODETAG_DEBUG_SESSION_RUNNING_PROG_RECEIVED_SIGINT_PAUSE_PROGRAM

    if (m_eCurrentDriverState == eDriverState_RunningDebugging)
        return MIstatus::success;

    // Driver cannot be in the following states to set eDriverState_RunningDebugging
    switch (m_eCurrentDriverState)
    {
        case eDriverState_NotRunning:
        case eDriverState_Initialising:
        case eDriverState_ShuttingDown:
        {
            SetErrorDescription(MIRSRC(IDS_DRIVER_ERR_DRIVER_STATE_ERROR));
            return MIstatus::failure;
        }
        case eDriverState_RunningDebugging:
        case eDriverState_RunningNotDebugging:
            break;
        case eDriverState_count:
            SetErrorDescription(CMIUtilString::Format(MIRSRC(IDS_CODE_ERR_INVALID_ENUMERATION_VALUE), "SetDriverStateRunningDebugging()"));
            return MIstatus::failure;
    }

    // Driver must be in this state to set eDriverState_RunningDebugging
    if (m_eCurrentDriverState != eDriverState_RunningNotDebugging)
    {
        SetErrorDescription(MIRSRC(IDS_DRIVER_ERR_DRIVER_STATE_ERROR));
        return MIstatus::failure;
    }

    m_eCurrentDriverState = eDriverState_RunningDebugging;

    return MIstatus::success;
}

//++ ------------------------------------------------------------------------------------
// Details: Prepare the client IDE so it will start working/communicating with *this MI
//          driver.
// Type:    Method.
// Args:    None.
// Return:  MIstatus::success - Functionality succeeded.
//          MIstatus::failure - Functionality failed.
// Throws:  None.
//--
bool
CMIDriver::InitClientIDEToMIDriver(void) const
{
    // Put other IDE init functions here
    return InitClientIDEEclipse();
}

//++ ------------------------------------------------------------------------------------
// Details: The IDE Eclipse when debugging locally expects "(gdb)\n" character
//          sequence otherwise it refuses to communicate and times out. This should be
//          sent to Eclipse before anything else.
// Type:    Method.
// Args:    None.
// Return:  MIstatus::success - Functionality succeeded.
//          MIstatus::failure - Functionality failed.
// Throws:  None.
//--
bool
CMIDriver::InitClientIDEEclipse(void) const
{
    std::cout << "(gdb)" << std::endl;

    return MIstatus::success;
}

//++ ------------------------------------------------------------------------------------
// Details: Ask *this driver whether it found an executable in the MI Driver's list of
//          arguments which to open and debug. If so instigate commands to set up a debug
//          session for that executable.
// Type:    Method.
// Args:    None.
// Return:  bool - True = True = Yes executable given as one of the parameters to the MI
//                 Driver.
//                 False = not found.
// Throws:  None.
//--
bool
CMIDriver::HaveExecutableFileNamePathOnCmdLine(void) const
{
    return m_bHaveExecutableFileNamePathOnCmdLine;
}

//++ ------------------------------------------------------------------------------------
// Details: Retrieve from *this driver executable file name path to start a debug session
//          with (if present see HaveExecutableFileNamePathOnCmdLine()).
// Type:    Method.
// Args:    None.
// Return:  CMIUtilString & - Executeable file name path or empty string.
// Throws:  None.
//--
const CMIUtilString &
CMIDriver::GetExecutableFileNamePathOnCmdLine(void) const
{
    return m_strCmdLineArgExecuteableFileNamePath;
}

//++ ------------------------------------------------------------------------------------
// Details: Execute commands (by injecting them into the stdin line queue container) and
//          other code to set up the MI Driver such that is can take the executable
//          argument passed on the command and create a debug session for it.
// Type:    Method.
// Args:    None.
// Return:  MIstatus::success - Functionality succeeded.
//          MIstatus::failure - Functionality failed.
// Throws:  None.
//--
bool
CMIDriver::LocalDebugSessionStartupInjectCommands(void)
{
    const CMIUtilString strCmd(CMIUtilString::Format("-file-exec-and-symbols %s", m_strCmdLineArgExecuteableFileNamePath.c_str()));

    return InjectMICommand(strCmd);
}

//++ ------------------------------------------------------------------------------------
// Details: Set the MI Driver into "its debugging an executable passed as an argument"
//          mode as against running via a client like Eclipse.
// Type:    Method.
// Args:    None.
// Return:  None.
// Throws:  None.
//--
void
CMIDriver::SetDriverDebuggingArgExecutable(void)
{
    m_bDriverDebuggingArgExecutable = true;
}

//++ ------------------------------------------------------------------------------------
// Details: Retrieve the MI Driver state indicating if it is operating in "its debugging
//          an executable passed as an argument" mode as against running via a client
//          like Eclipse.
// Type:    Method.
// Args:    None.
// Return:  None.
// Throws:  None.
//--
bool
CMIDriver::IsDriverDebuggingArgExecutable(void) const
{
    return m_bDriverDebuggingArgExecutable;
}