]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/tools/lldb-mi/MIDriver.cpp
Merge ^/head r274961 through r275386.
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / tools / lldb-mi / MIDriver.cpp
1 //===-- MIDriver.cpp --------------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 //++
11 // File:                MIDriver.cpp
12 //
13 // Overview:    CMIDriver implementation.
14 //
15 // Environment: Compilers:      Visual C++ 12.
16 //                                                      gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
17 //                              Libraries:      See MIReadmetxt. 
18 //
19 // Copyright:   None.
20 //--
21
22 // Third party headers:
23 #include <stdarg.h>             // va_list, va_start, var_end
24 #include <iostream>
25 #include <lldb/API/SBError.h>
26
27 // In-house headers:
28 #include "Driver.h"
29 #include "MIDriver.h"
30 #include "MICmnResources.h"
31 #include "MICmnLog.h"
32 #include "MICmdMgr.h"
33 #include "MICmnLLDBDebugger.h"
34 #include "MICmnMIResultRecord.h"
35 #include "MICmnMIValueConst.h"
36 #include "MICmnThreadMgrStd.h"
37 #include "MIUtilDebug.h"
38 #include "MIUtilSingletonHelper.h"
39 #include "MICmnStreamStdout.h"
40 #include "MICmnStreamStderr.h"
41 #include "MICmdArgValFile.h"
42 #include "MICmdArgValString.h"
43 #include "MICmnConfig.h"
44
45 // Instantiations:
46 #if _DEBUG
47         const CMIUtilString     CMIDriver::ms_constMIVersion = MIRSRC( IDS_MI_VERSION_DESCRIPTION_DEBUG );      
48 #else
49         const CMIUtilString     CMIDriver::ms_constMIVersion = MIRSRC( IDS_MI_VERSION_DESCRIPTION );    // Matches version in resources file
50 #endif // _DEBUG
51 const CMIUtilString     CMIDriver::ms_constAppNameShort( MIRSRC( IDS_MI_APPNAME_SHORT ) );
52 const CMIUtilString     CMIDriver::ms_constAppNameLong( MIRSRC( IDS_MI_APPNAME_LONG ) );
53
54 //++ ------------------------------------------------------------------------------------
55 // Details:     CMIDriver constructor.
56 // Type:        Method.
57 // Args:        None.
58 // Return:      None.
59 // Throws:      None.
60 //--
61 CMIDriver::CMIDriver( void )
62 :       m_bFallThruToOtherDriverEnabled( false )
63 ,       m_bDriverIsExiting( false )
64 ,       m_handleMainThread( 0 )
65 ,       m_rStdin( CMICmnStreamStdin::Instance() )
66 ,       m_rLldbDebugger( CMICmnLLDBDebugger::Instance() )
67 ,       m_rStdOut( CMICmnStreamStdout::Instance() )
68 ,       m_eCurrentDriverState( eDriverState_NotRunning )
69 ,       m_bHaveExecutableFileNamePathOnCmdLine( false )
70 ,       m_bDriverDebuggingArgExecutable( false )
71 {
72 }
73
74 //++ ------------------------------------------------------------------------------------
75 // Details:     CMIDriver destructor.
76 // Type:        Overridden.
77 // Args:        None.
78 // Return:      None.
79 // Throws:      None.
80 //--
81 CMIDriver::~CMIDriver( void )
82 {
83 }
84
85 //++ ------------------------------------------------------------------------------------
86 // Details:     Set whether *this driver (the parent) is enabled to pass a command to its 
87 //                      fall through (child) driver to interpret the command and do work instead
88 //                      (if *this driver decides it can't hanled the command).
89 // Type:        Method.
90 // Args:        vbYes   - (R) True = yes fall through, false = do not pass on command.
91 // Return:      MIstatus::success - Functional succeeded.
92 //                      MIstatus::failure - Functional failed.
93 // Throws:      None.
94 //--
95 bool CMIDriver::SetEnableFallThru( const bool vbYes )
96 {
97         m_bFallThruToOtherDriverEnabled = vbYes;
98         return MIstatus::success;
99 }
100
101 //++ ------------------------------------------------------------------------------------
102 // Details:     Get whether *this driver (the parent) is enabled to pass a command to its 
103 //                      fall through (child) driver to interpret the command and do work instead
104 //                      (if *this driver decides it can't hanled the command).
105 // Type:        Method.
106 // Args:        None.
107 // Return:      bool - True = yes fall through, false = do not pass on command.
108 // Throws:      None.
109 //--
110 bool CMIDriver::GetEnableFallThru( void ) const
111 {
112         return m_bFallThruToOtherDriverEnabled;
113 }
114
115 //++ ------------------------------------------------------------------------------------
116 // Details:     Retrieve MI's application name of itself.
117 // Type:        Method.
118 // Args:        None.
119 // Return:      CMIUtilString & - Text description.
120 // Throws:      None.
121 //--
122 const CMIUtilString & CMIDriver::GetAppNameShort( void ) const
123 {
124         return ms_constAppNameShort;
125 }
126
127 //++ ------------------------------------------------------------------------------------
128 // Details:     Retrieve MI's application name of itself.
129 // Type:        Method.
130 // Args:        None.
131 // Return:      CMIUtilString & - Text description.
132 // Throws:      None.
133 //--
134 const CMIUtilString & CMIDriver::GetAppNameLong( void ) const
135 {
136         return ms_constAppNameLong;
137 }
138
139 //++ ------------------------------------------------------------------------------------
140 // Details:     Retrieve MI's version description of itself.
141 // Type:        Method.
142 // Args:        None.
143 // Return:      CMIUtilString & - Text description.
144 // Throws:      None.
145 //--
146 const CMIUtilString & CMIDriver::GetVersionDescription( void ) const
147 {
148         return ms_constMIVersion;
149 }
150
151 //++ ------------------------------------------------------------------------------------
152 // Details:     Initialize setup *this driver ready for use.
153 // Type:        Method.
154 // Args:        None.
155 // Return:      MIstatus::success - Functional succeeded.
156 //                      MIstatus::failure - Functional failed.
157 // Throws:      None.
158 //--
159 bool CMIDriver::Initialize( void )
160 {
161         m_eCurrentDriverState = eDriverState_Initialising;
162         m_clientUsageRefCnt++;
163
164         ClrErrorDescription();
165
166         if( m_bInitialized )
167                 return MIstatus::success;
168
169         bool bOk = MIstatus::success;
170         CMIUtilString errMsg;
171
172         // Initialize all of the modules we depend on
173         MI::ModuleInit< CMICmnLog >         ( IDS_MI_INIT_ERR_LOG          , bOk, errMsg );
174         MI::ModuleInit< CMICmnStreamStdout >( IDS_MI_INIT_ERR_STREAMSTDOUT , bOk, errMsg );
175         MI::ModuleInit< CMICmnStreamStderr >( IDS_MI_INIT_ERR_STREAMSTDERR , bOk, errMsg );
176         MI::ModuleInit< CMICmnResources >   ( IDS_MI_INIT_ERR_RESOURCES    , bOk, errMsg );
177         MI::ModuleInit< CMICmnThreadMgrStd >( IDS_MI_INIT_ERR_THREADMANAGER, bOk, errMsg );
178         MI::ModuleInit< CMICmnStreamStdin > ( IDS_MI_INIT_ERR_STREAMSTDIN  , bOk, errMsg );
179         MI::ModuleInit< CMICmdMgr >         ( IDS_MI_INIT_ERR_CMDMGR       , bOk, errMsg );
180         bOk &= m_rLldbDebugger.SetDriver( *this );
181         MI::ModuleInit< CMICmnLLDBDebugger >( IDS_MI_INIT_ERR_LLDBDEBUGGER , bOk, errMsg );
182
183 #if MICONFIG_COMPILE_MIDRIVER_WITH_LLDBDRIVER
184         CMIDriverMgr & rDrvMgr = CMIDriverMgr::Instance();
185         bOk = bOk && rDrvMgr.RegisterDriver( *g_driver, "LLDB driver" );        // Will be pass thru driver
186         if( bOk )
187         {
188                 bOk = SetEnableFallThru( false ); // This is intentional at this time - yet to be fully implemented
189                 bOk = bOk && SetDriverToFallThruTo( *g_driver );
190                 CMIUtilString strOtherDrvErrMsg;
191                 if( bOk && GetEnableFallThru() && !g_driver->MISetup( strOtherDrvErrMsg ) )
192                 {
193                         bOk = false;
194                         errMsg = CMIUtilString::Format( MIRSRC( IDS_MI_INIT_ERR_FALLTHRUDRIVER ), strOtherDrvErrMsg.c_str()  );
195                 }
196         }
197 #endif // MICONFIG_COMPILE_MIDRIVER_WITH_LLDBDRIVER
198
199         m_bExitApp = false;
200                 
201         m_bInitialized = bOk;
202
203         if( !bOk )
204         {
205                 const CMIUtilString msg = CMIUtilString::Format( MIRSRC( IDS_MI_INIT_ERR_DRIVER ), errMsg.c_str() );
206                 SetErrorDescription( msg );
207                 return MIstatus::failure;
208         }
209
210         m_eCurrentDriverState = eDriverState_RunningNotDebugging;
211         
212         return bOk;
213 }
214
215 //++ ------------------------------------------------------------------------------------
216 // Details:     Unbind detach or release resources used by *this driver.
217 // Type:        Method.
218 // Args:        None.
219 // Return:      MIstatus::success - Functional succeeded.
220 //                      MIstatus::failure - Functional failed.
221 // Throws:      None.
222 //--
223 bool CMIDriver::Shutdown( void )
224 {
225         if( --m_clientUsageRefCnt > 0 )
226                 return MIstatus::success;
227         
228         if( !m_bInitialized )
229                 return MIstatus::success;
230
231         m_eCurrentDriverState = eDriverState_ShuttingDown;
232
233         ClrErrorDescription();
234
235         bool bOk = MIstatus::success;
236         CMIUtilString errMsg;
237
238         // Shutdown all of the modules we depend on
239         MI::ModuleShutdown< CMICmnLLDBDebugger >( IDS_MI_INIT_ERR_LLDBDEBUGGER , bOk, errMsg );
240         MI::ModuleShutdown< CMICmdMgr >         ( IDS_MI_INIT_ERR_CMDMGR       , bOk, errMsg );
241         MI::ModuleShutdown< CMICmnStreamStdin > ( IDS_MI_INIT_ERR_STREAMSTDIN  , bOk, errMsg );
242         MI::ModuleShutdown< CMICmnThreadMgrStd >( IDS_MI_INIT_ERR_THREADMANAGER, bOk, errMsg );
243         MI::ModuleShutdown< CMICmnResources >   ( IDS_MI_INIT_ERR_RESOURCES    , bOk, errMsg );
244         MI::ModuleShutdown< CMICmnStreamStderr >( IDS_MI_INIT_ERR_STREAMSTDERR , bOk, errMsg );
245         MI::ModuleShutdown< CMICmnStreamStdout >( IDS_MI_INIT_ERR_STREAMSTDOUT , bOk, errMsg );
246         MI::ModuleShutdown< CMICmnLog >         ( IDS_MI_INIT_ERR_LOG          , bOk, errMsg );
247                                                                                                                                                                          
248         if( !bOk )
249         {
250                 SetErrorDescriptionn( MIRSRC( IDS_MI_SHUTDOWN_ERR ), errMsg.c_str() );
251         }
252
253         m_eCurrentDriverState = eDriverState_NotRunning;
254
255         return bOk;
256 }
257
258 //++ ------------------------------------------------------------------------------------
259 // Details:     Work function. Client (the driver's user) is able to append their own message 
260 //                      in to the MI's Log trace file.
261 // Type:        Method.
262 // Args:        vMessage                - (R) Client's text message.
263 // Return:      MIstatus::success - Functional succeeded.
264 //                      MIstatus::failure - Functional failed.
265 // Throws:      None.
266 //--
267 bool CMIDriver::WriteMessageToLog( const CMIUtilString & vMessage )
268 {
269         CMIUtilString msg;
270         msg = CMIUtilString::Format( MIRSRC( IDS_MI_CLIENT_MSG ), vMessage.c_str() );
271         return m_pLog->Write( msg, CMICmnLog::eLogVerbosity_ClientMsg );
272 }
273
274 //++ ------------------------------------------------------------------------------------
275 // Details: CDriverMgr calls *this driver initialize setup ready for use.
276 // Type:        Overridden.
277 // Args:        None.
278 // Return:      MIstatus::success - Functional succeeded.
279 //                      MIstatus::failure - Functional failed.
280 // Throws:      None.
281 //--
282 bool CMIDriver::DoInitialize( void )
283 {
284         return CMIDriver::Instance().Initialize();
285 }
286
287 //++ ------------------------------------------------------------------------------------
288 // Details:     CDriverMgr calls *this driver to unbind detach or release resources used by 
289 //                      *this driver.
290 // Type:        Overridden.
291 // Args:        None.
292 // Return:      MIstatus::success - Functional succeeded.
293 //                      MIstatus::failure - Functional failed.
294 // Throws:      None.
295 //--
296 bool CMIDriver::DoShutdown( void )
297 {
298         return CMIDriver::Instance().Shutdown();
299 }
300
301 //++ ------------------------------------------------------------------------------------
302 // Details:     Retrieve the name for *this driver.
303 // Type:        Overridden.
304 // Args:        None.
305 // Return:      CMIUtilString & - Driver name.
306 // Throws:      None.
307 //--
308 const CMIUtilString & CMIDriver::GetName( void ) const
309 {
310         const CMIUtilString & rName = GetAppNameLong();
311         const CMIUtilString & rVsn = GetVersionDescription();
312         static CMIUtilString strName = CMIUtilString::Format( "%s %s", rName.c_str(), rVsn.c_str() );
313         
314         return strName;
315 }
316
317 //++ ------------------------------------------------------------------------------------
318 // Details:     Retrieve *this driver's last error condition.
319 // Type:        Overridden.
320 // Args:        None.
321 // Return:      CMIUtilString - Text description.
322 // Throws:      None.
323 //--
324 CMIUtilString CMIDriver::GetError( void ) const
325 {
326         return GetErrorDescription();
327 }
328
329 //++ ------------------------------------------------------------------------------------
330 // Details:     Call *this driver to resize the console window.
331 // Type:        Overridden.
332 // Args:        vTermWidth      - (R) New window column size.
333 // Return:      MIstatus::success - Functional succeeded.
334 //                      MIstatus::failure - Functional failed.
335 // Throws:      None.
336 //--
337 void CMIDriver::DoResizeWindow( const uint32_t vTermWidth )
338 {
339         GetTheDebugger().SetTerminalWidth( vTermWidth );
340 }
341
342 //++ ------------------------------------------------------------------------------------
343 // Details:     Call *this driver to return it's debugger.
344 // Type:        Overridden.
345 // Args:        None.
346 // Return:      lldb::SBDebugger & - LLDB debugger object reference.
347 // Throws:      None.
348 //--
349 lldb::SBDebugger & CMIDriver::GetTheDebugger( void )
350 {
351         return m_rLldbDebugger.GetTheDebugger();
352 }
353
354 //++ ------------------------------------------------------------------------------------
355 // Details:     Specify another driver *this driver can call should this driver not be able 
356 //                      to handle the client data input. DoFallThruToAnotherDriver() makes the call.
357 // Type:        Overridden.
358 // Args:        vrOtherDriver   - (R) Reference to another driver object.
359 // Return:      MIstatus::success - Functional succeeded.
360 //                      MIstatus::failure - Functional failed.
361 // Throws:      None.
362 //--
363 bool CMIDriver::SetDriverToFallThruTo( const CMIDriverBase & vrOtherDriver )
364 {
365         m_pDriverFallThru = const_cast< CMIDriverBase * >( &vrOtherDriver );
366
367         return m_pDriverFallThru->SetDriverParent( *this );
368 }
369
370 //++ ------------------------------------------------------------------------------------
371 // Details:     Proxy function CMIDriverMgr IDriver interface implementation. *this driver's
372 //                      implementation called from here to match the existing function name of the 
373 //                      original LLDb driver class (the extra indirection is not necessarily required).
374 //                      Check the arguments that were passed to this program to make sure they are 
375 //                      valid and to get their argument values (if any).
376 // Type:        Overridden.
377 // Args:        argc            - (R)   An integer that contains the count of arguments that follow in 
378 //                                                              argv. The argc parameter is always greater than or equal to 1.
379 //                      argv            - (R)   An array of null-terminated strings representing command-line 
380 //                                                              arguments entered by the user of the program. By convention, 
381 //                                                              argv[0] is the command with which the program is invoked.
382 //                      vpStdOut        - (R)   Pointer to a standard output stream. 
383 //                      vwbExiting      - (W)   True = *this want to exit, Reasons: help, invalid arg(s),
384 //                                                              version information only.
385 //                                                              False = Continue to work, start debugger i.e. Command 
386 //                                                              interpreter. 
387 // Return:      lldb::SBError - LLDB current error status.
388 // Throws:      None.
389 //--
390 lldb::SBError CMIDriver::DoParseArgs( const int argc, const char * argv[], FILE * vpStdOut, bool & vwbExiting )
391 {
392         return ParseArgs( argc, argv, vpStdOut, vwbExiting );
393 }
394
395 //++ ------------------------------------------------------------------------------------
396 // Details:     Check the arguments that were passed to this program to make sure they are 
397 //                      valid and to get their argument values (if any). The following are options 
398 //                      that are only handled by *this driver: 
399 //                              --executable 
400 //                      The application's options --interpreter and --executable in code act very similar.
401 //                      The --executable is necessary to differentiate whither the MI Driver is being
402 //                      using by a client i.e. Eclipse or from the command line. Eclipse issues the option
403 //                      --interpreter and also passes additional arguments which can be interpreted as an
404 //                      executable if called from the command line. Using --executable tells the MI 
405 //                      Driver is being called the command line and that the executable argument is indeed
406 //                      a specified executable an so actions commands to set up the executable for a 
407 //                      debug session. Using --interpreter on the commnd line does not action additional
408 //                      commands to initialise a debug session and so be able to launch the process.
409 // Type:        Overridden.
410 // Args:        argc            - (R)   An integer that contains the count of arguments that follow in 
411 //                                                              argv. The argc parameter is always greater than or equal to 1.
412 //                      argv            - (R)   An array of null-terminated strings representing command-line 
413 //                                                              arguments entered by the user of the program. By convention, 
414 //                                                              argv[0] is the command with which the program is invoked.
415 //                      vpStdOut        - (R)   Pointer to a standard output stream. 
416 //                      vwbExiting      - (W)   True = *this want to exit, Reasons: help, invalid arg(s),
417 //                                                              version information only.
418 //                                                              False = Continue to work, start debugger i.e. Command 
419 //                                                              interpreter. 
420 // Return:      lldb::SBError - LLDB current error status.
421 // Throws:      None.
422 //--
423 lldb::SBError CMIDriver::ParseArgs( const int argc, const char * argv[], FILE * vpStdOut, bool & vwbExiting )
424 {
425         lldb::SBError errStatus;
426         const bool bHaveArgs( argc >= 2 );
427         
428         // *** Add any args handled here to GetHelpOnCmdLineArgOptions() ***
429         
430         // CODETAG_MIDRIVE_CMD_LINE_ARG_HANDLING
431         // Look for the command line options            
432         bool bHaveExecutableFileNamePath = false;
433         bool bHaveExecutableLongOption = false;
434         
435         if( bHaveArgs )
436         {
437                 // Search right to left to look for the executable
438                 for( MIint i = argc - 1; i > 0; i-- ) 
439                 { 
440                         const CMIUtilString strArg( argv[ i ] );
441                         const CMICmdArgValFile argFile;
442                         if( argFile.IsFilePath( strArg  ) || 
443                                 CMICmdArgValString( true, false, true ).IsStringArg( strArg ))
444                         {
445                                 bHaveExecutableFileNamePath = true;
446                                 m_strCmdLineArgExecuteableFileNamePath = argFile.GetFileNamePath( strArg );
447                                 m_bHaveExecutableFileNamePathOnCmdLine = true;
448                         }
449                         // This argument is also check for in CMIDriverMgr::ParseArgs()
450                         if( 0 == strArg.compare( "--executable" ) )     // Used to specify that there is executable argument also on the command line 
451                         {                                                                                       // See fn description.
452                                    bHaveExecutableLongOption = true;
453                         }
454                 }
455         }
456
457         if( bHaveExecutableFileNamePath && bHaveExecutableLongOption )
458         {
459                 // CODETAG_CMDLINE_ARG_EXECUTABLE_DEBUG_SESSION
460 #if MICONFIG_ENABLE_MI_DRIVER_MI_MODE_CMDLINE_ARG_EXECUTABLE_DEBUG_SESSION
461                 SetDriverDebuggingArgExecutable();
462 #else
463                 vwbExiting = true;
464                 errStatus.SetErrorString( MIRSRC( IDS_DRIVER_ERR_LOCAL_DEBUG_NOT_IMPL ) );
465 #endif // MICONFIG_ENABLE_MI_DRIVER_MI_MODE_CMDLINE_ARG_EXECUTABLE_DEBUG_SESSION
466         }
467
468         return errStatus;
469 }
470
471 //++ ------------------------------------------------------------------------------------
472 // Details:     A client can ask if *this driver is GDB/MI compatible.
473 // Type:        Overridden.
474 // Args:        None.
475 // Return:      True - GBD/MI compatible LLDB front end.
476 //                      False - Not GBD/MI compatible LLDB front end.
477 // Throws:      None.
478 //--
479 bool CMIDriver::GetDriverIsGDBMICompatibleDriver( void ) const
480 {
481         return true;
482 }
483
484 //++ ------------------------------------------------------------------------------------
485 // Details:     Callback function for monitoring stream stdin object. Part of the visitor 
486 //                      pattern. 
487 //                      This function is called by the CMICmnStreamStdin::CThreadStdin
488 //                      "stdin monitor" thread (ID).
489 // Type:        Overridden.
490 // Args:        vStdInBuffer    - (R) Copy of the current stdin line data.
491 //                      vrbYesExit              - (RW) True = yes exit stdin monitoring, false = continue monitor.
492 // Return:      MIstatus::success - Functional succeeded.
493 //                      MIstatus::failure - Functional failed.
494 // Throws:      None.
495 //--
496 bool CMIDriver::ReadLine( const CMIUtilString & vStdInBuffer, bool & vrwbYesExit )
497 {
498         // For debugging. Update prompt show stdin is working
499         //printf( "%s\n", vStdInBuffer.c_str() );
500         //fflush( stdout );
501
502         // Special case look for the quit command here so stop monitoring stdin stream
503         // So we do not go back to fgetc() and wait and hang thread on exit
504         if( vStdInBuffer == "quit" )
505                 vrwbYesExit = true;
506
507         // 1. Put new line in the queue container by stdin monitor thread
508         // 2. Then *this driver calls ReadStdinLineQueue() when ready to read the queue in its
509         // own thread
510         const bool bOk = QueueMICommand( vStdInBuffer );
511
512         // Check to see if the *this driver is shutting down (exit application)
513         if( !vrwbYesExit )
514                 vrwbYesExit = m_bDriverIsExiting;
515
516         return bOk;
517 }
518
519 //++ ------------------------------------------------------------------------------------
520 // Details:     Start worker threads for the driver.
521 // Type:        Method.
522 // Args:        None.
523 // Return:      MIstatus::success - Functional succeeded.
524 //                      MIstatus::failure - Functional failed.
525 // Throws:      None.
526 //--
527 bool CMIDriver::StartWorkerThreads( void )
528 {
529         bool bOk = MIstatus::success;
530         
531         // Grab the thread manager
532         CMICmnThreadMgrStd & rThreadMgr = CMICmnThreadMgrStd::Instance();
533
534         // Start the stdin thread
535         bOk &= m_rStdin.SetVisitor( *this );
536         if( bOk && !rThreadMgr.ThreadStart< CMICmnStreamStdin >( m_rStdin ))
537         {
538                 const CMIUtilString errMsg = CMIUtilString::Format( MIRSRC( IDS_THREADMGR_ERR_THREAD_FAIL_CREATE ), CMICmnThreadMgrStd::Instance().GetErrorDescription().c_str() );
539                 SetErrorDescriptionn( errMsg );
540                 return MIstatus::failure;
541         }
542
543         // Start the event polling thread
544         if( bOk && !rThreadMgr.ThreadStart< CMICmnLLDBDebugger >( m_rLldbDebugger ) )
545         {
546                 const CMIUtilString errMsg = CMIUtilString::Format( MIRSRC( IDS_THREADMGR_ERR_THREAD_FAIL_CREATE ), CMICmnThreadMgrStd::Instance().GetErrorDescription().c_str() );
547                 SetErrorDescriptionn( errMsg );
548                 return MIstatus::failure;
549         }
550
551         return bOk;
552 }
553
554 //++ ------------------------------------------------------------------------------------
555 // Details:     Stop worker threads for the driver.
556 // Type:        Method.
557 // Args:        None.
558 // Return:      MIstatus::success - Functional succeeded.
559 //                      MIstatus::failure - Functional failed.
560 // Throws:      None.
561 //--
562 bool CMIDriver::StopWorkerThreads( void )
563 {
564         CMICmnThreadMgrStd & rThreadMgr = CMICmnThreadMgrStd::Instance();
565         return rThreadMgr.ThreadAllTerminate();
566 }
567
568 //++ ------------------------------------------------------------------------------------
569 // Details:     Call this function puts *this driver to work.
570 //                      This function is used by the application's main thread.
571 // Type:        Overridden.
572 // Args:        None.
573 // Return:      MIstatus::success - Functional succeeded.
574 //                      MIstatus::failure - Functional failed.
575 // Throws:      None.
576 //--
577 bool CMIDriver::DoMainLoop( void )
578 {
579         if( !InitClientIDEToMIDriver() ) // Init Eclipse IDE
580         {
581                 SetErrorDescriptionn( MIRSRC( IDS_MI_INIT_ERR_CLIENT_USING_DRIVER ) );
582                 return MIstatus::failure;
583         }
584
585         if( !StartWorkerThreads() )
586                 return MIstatus::failure;
587         
588         // App is not quitting currently
589         m_bExitApp = false;
590
591         // CODETAG_CMDLINE_ARG_EXECUTABLE_DEBUG_SESSION
592 #if MICONFIG_ENABLE_MI_DRIVER_MI_MODE_CMDLINE_ARG_EXECUTABLE_DEBUG_SESSION
593         if( HaveExecutableFileNamePathOnCmdLine() )
594         {
595                 if( !LocalDebugSessionStartupInjectCommands() )
596                 {
597                         SetErrorDescription( MIRSRC( IDS_MI_INIT_ERR_LOCAL_DEBUG_SESSION ) );
598                         return MIstatus::failure;
599                 }
600         }
601 #endif // MICONFIG_ENABLE_MI_DRIVER_MI_MODE_CMDLINE_ARG_EXECUTABLE_DEBUG_SESSION
602
603         // While the app is active
604         while( !m_bExitApp )
605         {
606                 // Poll stdin queue and dispatch
607                 if( !ReadStdinLineQueue() )
608                 {
609                         // Something went wrong
610                         break;
611                 }
612         }
613
614         // Signal that the application is shutting down
615         DoAppQuit();
616
617         // Close and wait for the workers to stop
618         StopWorkerThreads();
619
620         // Ensure that a new line is sent as the last act of the dying driver
621         m_rStdOut.WriteMIResponse( "\n", false );
622
623         return MIstatus::success;
624 }
625
626 //++ ------------------------------------------------------------------------------------
627 // Details:     *this driver sits and waits for input to the stdin line queue shared by *this
628 //                      driver and the stdin monitor thread, it queues, *this reads, interprets and
629 //                      reacts.
630 //                      This function is used by the application's main thread.
631 // Type:        Method.
632 // Args:        None.
633 // Return:      MIstatus::success - Functional succeeded.
634 //                      MIstatus::failure - Functional failed.
635 // Throws:      None.
636 //--
637 bool CMIDriver::ReadStdinLineQueue( void )
638 {
639         // True when queue contains input
640         bool bHaveInput = false;
641
642         // Stores the current input line
643         CMIUtilString lineText;
644         {
645                 // Lock while we access the queue
646                 CMIUtilThreadLock lock( m_threadMutex );
647                 if( !m_queueStdinLine.empty() )
648                 {
649                         lineText = m_queueStdinLine.front();
650                         m_queueStdinLine.pop();
651                         bHaveInput = !lineText.empty();
652                 }
653         }
654
655         // Process while we have input
656         if( bHaveInput )
657         {
658                 if( lineText == "quit" )
659                 {
660                         // We want to be exiting when receiving a quit command
661                         m_bExitApp = true;
662                         return MIstatus::success;
663                 }
664
665                 // Process the command
666                 const bool bOk = InterpretCommand( lineText );
667
668                 // Draw prompt if desired
669                 if( bOk && m_rStdin.GetEnablePrompt() )
670                         m_rStdOut.WriteMIResponse( m_rStdin.GetPrompt() );
671
672                 // Input has been processed
673                 bHaveInput = false;
674         }
675         else
676         {
677                 // Give resources back to the OS
678                 const std::chrono::milliseconds time( 1 );
679                 std::this_thread::sleep_for( time );
680         }
681         
682         return MIstatus::success;
683 }
684
685 //++ ------------------------------------------------------------------------------------
686 // Details:     Set things in motion, set state etc that brings *this driver (and the 
687 //                      application) to a tidy shutdown.
688 //                      This function is used by the application's main thread.
689 // Type:        Method.
690 // Args:        None.
691 // Return:      MIstatus::success - Functional succeeded.
692 //                      MIstatus::failure - Functional failed.
693 // Throws:      None.
694 //--
695 bool CMIDriver::DoAppQuit( void )
696 {
697         bool bYesQuit = true;
698
699         // Shutdown stuff, ready app for exit
700         {
701                 CMIUtilThreadLock lock( m_threadMutex );
702                 m_bDriverIsExiting = true;
703         }
704
705         return bYesQuit;
706 }
707
708 //++ ------------------------------------------------------------------------------------
709 // Details:     *this driver passes text commands to a fall through driver is it does not
710 //                      understand them (the LLDB driver).
711 //                      This function is used by the application's main thread.
712 // Type:        Method.
713 // Args:        vTextLine                       - (R) Text data representing a possible command.
714 //                      vwbCmdYesValid          - (W) True = Command valid, false = command not handled.
715 // Return:      MIstatus::success - Functional succeeded.
716 //                      MIstatus::failure - Functional failed.
717 // Throws:      None.
718 //--
719 bool CMIDriver::InterpretCommandFallThruDriver( const CMIUtilString & vTextLine, bool & vwbCmdYesValid )
720 {
721         MIunused( vTextLine );
722         MIunused( vwbCmdYesValid );
723
724         // ToDo: Implement when less urgent work to be done or decide remove as not required
725         //bool bOk = MIstatus::success;
726         //bool bCmdNotUnderstood = true;
727         //if( bCmdNotUnderstood && GetEnableFallThru() )
728         //{
729         //      CMIUtilString errMsg;
730         //      bOk = DoFallThruToAnotherDriver( vStdInBuffer, errMsg );
731         //      if( !bOk )
732         //      {
733         //              errMsg = errMsg.StripCREndOfLine();
734         //              errMsg = errMsg.StripCRAll();
735         //              const CMIDriverBase * pOtherDriver = GetDriverToFallThruTo();
736         //              const MIchar * pName = pOtherDriver->GetDriverName().c_str();
737         //              const MIchar * pId = pOtherDriver->GetDriverId().c_str();
738         //              const CMIUtilString msg( CMIUtilString::Format( MIRSRC( IDS_DRIVER_ERR_FALLTHRU_DRIVER_ERR ), pName, pId, errMsg.c_str() ) );
739         //              m_pLog->WriteMsg( msg );
740         //      }
741         //}
742         //
743         //vwbCmdYesValid = bOk;
744         //CMIUtilString strNot;
745         //if( vwbCmdYesValid)
746         //      strNot = CMIUtilString::Format( "%s ", MIRSRC( IDS_WORD_NOT ) );
747         //const CMIUtilString msg( CMIUtilString::Format( MIRSRC( IDS_FALLTHRU_DRIVER_CMD_RECEIVED ), vTextLine.c_str(), strNot.c_str() ) );
748         //m_pLog->WriteLog( msg );
749         
750         return MIstatus::success;
751 }
752
753 //++ ------------------------------------------------------------------------------------
754 // Details:     Retrieve the name for *this driver.
755 // Type:        Overridden.
756 // Args:        None.
757 // Return:      CMIUtilString & - Driver name.
758 // Throws:      None.
759 //--
760 const CMIUtilString & CMIDriver::GetDriverName( void ) const
761 {
762         return GetName();
763 }
764
765 //++ ------------------------------------------------------------------------------------
766 // Details:     Get the unique ID for *this driver.
767 // Type:        Overridden.
768 // Args:        None.
769 // Return:      CMIUtilString & - Text description.
770 // Throws:      None.
771 //--
772 const CMIUtilString & CMIDriver::GetDriverId( void ) const
773 {
774         return GetId();
775 }
776
777 //++ ------------------------------------------------------------------------------------
778 // Details:     This function allows *this driver to call on another driver to perform work
779 //                      should this driver not be able to handle the client data input.
780 //                      SetDriverToFallThruTo() specifies the fall through to driver.
781 //                      Check the error message if the function returns a failure.
782 // Type:        Overridden.
783 // Args:        vCmd            - (R) Command instruction to interpret.
784 //                      vwErrMsg        - (W) Error description on command failing.
785 // Return:      MIstatus::success - Command succeeded.
786 //                      MIstatus::failure - Command failed.
787 // Throws:      None.
788 //--
789 bool CMIDriver::DoFallThruToAnotherDriver( const CMIUtilString & vCmd, CMIUtilString & vwErrMsg )
790 {
791         bool bOk = MIstatus::success;
792
793         CMIDriverBase * pOtherDriver = GetDriverToFallThruTo();
794         if( pOtherDriver == nullptr )
795                 return bOk;
796
797         return pOtherDriver->DoFallThruToAnotherDriver( vCmd, vwErrMsg );
798 }
799
800 //++ ------------------------------------------------------------------------------------
801 // Details:     *this driver provides a file stream to other drivers on which *this driver
802 //                      write's out to and they read as expected input. *this driver is passing
803 //                      through commands to the (child) pass through assigned driver.
804 // Type:        Overrdidden.
805 // Args:        None.
806 // Return:      FILE * - Pointer to stream.
807 // Throws:      None.
808 //--
809 FILE * CMIDriver::GetStdin( void ) const
810 {
811         // Note this fn is called on CMIDriverMgr register driver so stream has to be
812         // available before *this driver has been initialized! Flaw?
813
814         // This very likely to change later to a stream that the pass thru driver
815         // will read and we write to give it 'input'
816         return stdin;
817 }
818
819 //++ ------------------------------------------------------------------------------------
820 // Details:     *this driver provides a file stream to other pass through assigned drivers 
821 //                      so they know what to write to.
822 // Type:        Overidden.
823 // Args:        None.
824 // Return:      FILE * - Pointer to stream.
825 // Throws:      None.
826 //--
827 FILE * CMIDriver::GetStdout( void ) const
828 {
829         // Note this fn is called on CMIDriverMgr register driver so stream has to be
830         // available before *this driver has been initialized! Flaw?
831
832         // Do not want to pass through driver to write to stdout
833         return NULL;
834 }
835
836 //++ ------------------------------------------------------------------------------------
837 // Details:     *this driver provides a error file stream to other pass through assigned drivers 
838 //                      so they know what to write to.
839 // Type:        Overidden.
840 // Args:        None.
841 // Return:      FILE * - Pointer to stream.
842 // Throws:      None.
843 //--
844 FILE * CMIDriver::GetStderr( void ) const
845 {
846         // Note this fn is called on CMIDriverMgr register driver so stream has to be
847         // available before *this driver has been initialized! Flaw?
848
849         // This very likely to change later to a stream that the pass thru driver
850         // will write to and *this driver reads from to pass on the CMICmnLog object
851         return stderr;
852 }
853
854 //++ ------------------------------------------------------------------------------------
855 // Details:     Set a unique ID for *this driver. It cannot be empty.
856 // Type:        Overridden.
857 // Args:        vId     - (R) Text description.
858 // Return:      MIstatus::success - Functional succeeded.
859 //                      MIstatus::failure - Functional failed.
860 // Throws:      None.
861 //--
862 bool CMIDriver::SetId( const CMIUtilString & vId )
863 {
864         if( vId.empty() )
865         {
866                 SetErrorDescriptionn( MIRSRC( IDS_DRIVER_ERR_ID_INVALID ), GetName().c_str(), vId.c_str() );
867                 return MIstatus::failure;
868         }
869
870         m_strDriverId = vId;
871         return MIstatus::success;
872 }
873
874 //++ ------------------------------------------------------------------------------------
875 // Details:     Get the unique ID for *this driver.
876 // Type:        Overridden.
877 // Args:        None.
878 // Return:      CMIUtilString & - Text description.
879 // Throws:      None.
880 //--
881 const CMIUtilString & CMIDriver::GetId( void ) const
882 {
883         return m_strDriverId;
884 }
885
886 //++ ------------------------------------------------------------------------------------
887 // Details:     Inject a command into the command processing system to be interpreted as a
888 //                      command read from stdin. The text representing the command is also written
889 //                      out to stdout as the command did not come from via stdin.
890 // Type:        Method.
891 // Args:        vMICmd  - (R) Text data representing a possible command.
892 // Return:      MIstatus::success - Functional succeeded.
893 //                      MIstatus::failure - Functional failed.
894 // Throws:      None.
895 //--
896 bool CMIDriver::InjectMICommand( const CMIUtilString & vMICmd )
897 {
898         const bool bOk = m_rStdOut.WriteMIResponse( vMICmd );
899
900         return bOk && QueueMICommand( vMICmd );
901 }
902
903 //++ ------------------------------------------------------------------------------------
904 // Details:     Add a new command candidate to the command queue to be processed by the 
905 //                      command system.
906 // Type:        Method.
907 // Args:        vMICmd  - (R) Text data representing a possible command.
908 // Return:      MIstatus::success - Functional succeeded.
909 //                      MIstatus::failure - Functional failed.
910 // Throws:      None.
911 //--
912 bool CMIDriver::QueueMICommand( const CMIUtilString & vMICmd )
913 {
914         CMIUtilThreadLock lock( m_threadMutex );
915         m_queueStdinLine.push( vMICmd );
916         
917         return MIstatus::success;
918 }
919         
920 //++ ------------------------------------------------------------------------------------
921 // Details:     Interpret the text data and match against current commands to see if there 
922 //                      is a match. If a match then the command is issued and actioned on. The 
923 //                      text data if not understood by *this driver is past on to the Fall Thru
924 //                      driver.
925 //                      This function is used by the application's main thread.
926 // Type:        Method.
927 // Args:        vTextLine       - (R) Text data representing a possible command.
928 // Return:      MIstatus::success - Functional succeeded.
929 //                      MIstatus::failure - Functional failed.
930 // Throws:      None.
931 //--
932 bool CMIDriver::InterpretCommand( const CMIUtilString & vTextLine )
933 {
934         bool bCmdYesValid = false;
935         bool bOk = InterpretCommandThisDriver( vTextLine, bCmdYesValid );
936         if( bOk && !bCmdYesValid )
937                 bOk = InterpretCommandFallThruDriver( vTextLine, bCmdYesValid );
938
939         return bOk;
940 }
941
942 //++ ------------------------------------------------------------------------------------
943 // Details:     Interpret the text data and match against current commands to see if there 
944 //                      is a match. If a match then the command is issued and actioned on. If a
945 //                      command cannot be found to match then vwbCmdYesValid is set to false and
946 //                      nothing else is done here.
947 //                      This function is used by the application's main thread.
948 // Type:        Method.
949 // Args:        vTextLine                       - (R) Text data representing a possible command.
950 //                      vwbCmdYesValid          - (W) True = Command invalid, false = command acted on.
951 // Return:      MIstatus::success - Functional succeeded.
952 //                      MIstatus::failure - Functional failed.
953 // Throws:      None.
954 //--
955 bool CMIDriver::InterpretCommandThisDriver( const CMIUtilString & vTextLine, bool & vwbCmdYesValid )
956 {
957         vwbCmdYesValid = false;
958
959         bool bCmdNotInCmdFactor = false;
960         SMICmdData cmdData;
961         CMICmdMgr & rCmdMgr = CMICmdMgr::Instance();
962         if( !rCmdMgr.CmdInterpret( vTextLine, vwbCmdYesValid, bCmdNotInCmdFactor, cmdData ) )
963                 return MIstatus::failure;
964         
965         if( vwbCmdYesValid )
966         {
967                 // For debugging only
968                 //m_pLog->WriteLog( cmdData.strMiCmdAll.c_str() );
969                 
970                 return ExecuteCommand( cmdData );
971         }
972
973         // Check for escape character, may be cursor control characters
974         // This code is not necessary for application operation, just want to keep tabs on what 
975         // is been given to the driver to try and intepret.
976         if( vTextLine.at( 0 ) == 27 )
977         {
978                 CMIUtilString logInput( MIRSRC( IDS_STDIN_INPUT_CTRL_CHARS ) );
979                 for( MIuint i = 0; i < vTextLine.length(); i++ )
980                 {
981                         logInput += CMIUtilString::Format( "%d ", vTextLine.at( i ) );
982                 }
983                 m_pLog->WriteLog( logInput );
984                 return MIstatus::success;
985         }
986
987         // Write to the Log that a 'command' was not valid. 
988         // Report back to the MI client via MI result record.
989         CMIUtilString strNotInCmdFactory;
990         if( bCmdNotInCmdFactor )
991                 strNotInCmdFactory = CMIUtilString::Format( MIRSRC( IDS_DRIVER_CMD_NOT_IN_FACTORY ), cmdData.strMiCmd.c_str() );
992         const CMIUtilString strNot( CMIUtilString::Format( "%s ", MIRSRC( IDS_WORD_NOT ) ) );
993         const CMIUtilString msg( CMIUtilString::Format( MIRSRC( IDS_DRIVER_CMD_RECEIVED ), vTextLine.c_str(), strNot.c_str(), strNotInCmdFactory.c_str() ) );
994         const CMICmnMIValueConst vconst = CMICmnMIValueConst( msg );
995         const CMICmnMIValueResult valueResult( "msg", vconst );
996         const CMICmnMIResultRecord miResultRecord( cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, valueResult );
997         m_rStdOut.WriteMIResponse( miResultRecord.GetString() );
998         
999         // Proceed to wait for or execute next command
1000         return MIstatus::success;
1001 }
1002
1003 //++ ------------------------------------------------------------------------------------
1004 // Details:     Having previously had the potential command validated and found valid now
1005 //                      get the command executed.
1006 //                      This function is used by the application's main thread.
1007 // Type:        Method.
1008 // Args:        vCmdData        - (RW) Command meta data.
1009 // Return:      MIstatus::success - Functional succeeded.
1010 //                      MIstatus::failure - Functional failed.
1011 // Throws:      None.
1012 //--
1013 bool CMIDriver::ExecuteCommand( const SMICmdData & vCmdData )
1014 {
1015         CMICmdMgr & rCmdMgr = CMICmdMgr::Instance();
1016         return rCmdMgr.CmdExecute( vCmdData );
1017 }
1018
1019 //++ ------------------------------------------------------------------------------------
1020 // Details:     Set the MI Driver's exit application flag. The application checks this flag 
1021 //                      after every stdin line is read so the exit may not be instantaneous.
1022 //                      If vbForceExit is false the MI Driver queries its state and determines if is
1023 //                      should exit or continue operating depending on that running state.
1024 //                      This is related to the running state of the MI driver.
1025 // Type:        Overridden.
1026 // Args:        None.
1027 // Return:      None.
1028 // Throws:      None.
1029 //--
1030 void CMIDriver::SetExitApplicationFlag( const bool vbForceExit )
1031 {
1032         if( vbForceExit )
1033         {
1034                 CMIUtilThreadLock lock( m_threadMutex );
1035                 m_bExitApp = true;
1036                 return;
1037         }
1038
1039         // CODETAG_DEBUG_SESSION_RUNNING_PROG_RECEIVED_SIGINT_PAUSE_PROGRAM
1040         // Did we receive a SIGINT from the client during a running debug program, if
1041         // so then SIGINT is not to be taken as meaning kill the MI driver application
1042         // but halt the inferior program being debugged instead
1043         if( m_eCurrentDriverState == eDriverState_RunningDebugging )
1044         {
1045                 InjectMICommand( "-exec-interrupt" );
1046                 return;
1047         }
1048
1049         m_bExitApp = true;
1050 }
1051
1052 //++ ------------------------------------------------------------------------------------
1053 // Details:     Get the  MI Driver's exit exit application flag. 
1054 //                      This is related to the running state of the MI driver.
1055 // Type:        Method.
1056 // Args:        None.
1057 // Return:      bool    - True = MI Driver is shutting down, false = MI driver is running.
1058 // Throws:      None.
1059 //--
1060 bool CMIDriver::GetExitApplicationFlag( void ) const
1061 {
1062         return m_bExitApp;
1063 }
1064
1065 //++ ------------------------------------------------------------------------------------
1066 // Details:     Get the current running state of the MI Driver. 
1067 // Type:        Method.
1068 // Args:        None.
1069 // Return:      DriverState_e   - The current running state of the application.
1070 // Throws:      None.
1071 //--
1072 CMIDriver::DriverState_e CMIDriver::GetCurrentDriverState( void ) const
1073 {
1074         return m_eCurrentDriverState;
1075 }
1076
1077 //++ ------------------------------------------------------------------------------------
1078 // Details:     Set the current running state of the MI Driver to running and currently not in
1079 //                      a debug session. 
1080 // Type:        Method.
1081 // Return:      MIstatus::success - Functionality succeeded.
1082 //                      MIstatus::failure - Functionality failed.
1083 // Return:      DriverState_e   - The current running state of the application.
1084 // Throws:      None.
1085 //--
1086 bool CMIDriver::SetDriverStateRunningNotDebugging( void )
1087 {
1088         // CODETAG_DEBUG_SESSION_RUNNING_PROG_RECEIVED_SIGINT_PAUSE_PROGRAM
1089                 
1090         if( m_eCurrentDriverState == eDriverState_RunningNotDebugging )
1091                 return MIstatus::success;
1092
1093         // Driver cannot be in the following states to set eDriverState_RunningNotDebugging
1094         switch( m_eCurrentDriverState )
1095         {
1096         case eDriverState_NotRunning:
1097         case eDriverState_Initialising:
1098         case eDriverState_ShuttingDown:
1099         {
1100                 SetErrorDescription( MIRSRC( IDS_DRIVER_ERR_DRIVER_STATE_ERROR ) );
1101                 return MIstatus::failure;
1102         }
1103         case eDriverState_RunningDebugging:
1104         case eDriverState_RunningNotDebugging:
1105                 break;
1106         case eDriverState_count:
1107         default:
1108                 SetErrorDescription( CMIUtilString::Format( MIRSRC( IDS_CODE_ERR_INVALID_ENUMERATION_VALUE ), "SetDriverStateRunningNotDebugging()" ) );
1109                 return MIstatus::failure;
1110         }
1111
1112         // Driver must be in this state to set eDriverState_RunningNotDebugging
1113         if( m_eCurrentDriverState != eDriverState_RunningDebugging )
1114         {
1115                 SetErrorDescription( MIRSRC( IDS_DRIVER_ERR_DRIVER_STATE_ERROR ) );
1116                 return MIstatus::failure;
1117         }
1118
1119         m_eCurrentDriverState = eDriverState_RunningNotDebugging;
1120
1121         return MIstatus::success;
1122 }
1123
1124 //++ ------------------------------------------------------------------------------------
1125 // Details:     Set the current running state of the MI Driver to running and currently not in
1126 //                      a debug session. The driver's state must in the state running and in a
1127 //                      debug session to set this new state.
1128 // Type:        Method.
1129 // Return:      MIstatus::success - Functionality succeeded.
1130 //                      MIstatus::failure - Functionality failed.
1131 // Return:      DriverState_e   - The current running state of the application.
1132 // Throws:      None.
1133 //--
1134 bool CMIDriver::SetDriverStateRunningDebugging( void )
1135 {
1136         // CODETAG_DEBUG_SESSION_RUNNING_PROG_RECEIVED_SIGINT_PAUSE_PROGRAM
1137                 
1138         if( m_eCurrentDriverState == eDriverState_RunningDebugging )
1139                 return MIstatus::success;
1140
1141         // Driver cannot be in the following states to set eDriverState_RunningDebugging
1142         switch( m_eCurrentDriverState )
1143         {
1144         case eDriverState_NotRunning:
1145         case eDriverState_Initialising:
1146         case eDriverState_ShuttingDown:
1147         {
1148                 SetErrorDescription( MIRSRC( IDS_DRIVER_ERR_DRIVER_STATE_ERROR ) );
1149                 return MIstatus::failure;
1150         }
1151         case eDriverState_RunningDebugging:
1152         case eDriverState_RunningNotDebugging:
1153                 break;
1154         case eDriverState_count:
1155         default:
1156                 SetErrorDescription( CMIUtilString::Format( MIRSRC( IDS_CODE_ERR_INVALID_ENUMERATION_VALUE ), "SetDriverStateRunningDebugging()" ) );
1157                 return MIstatus::failure;
1158         }
1159
1160         // Driver must be in this state to set eDriverState_RunningDebugging
1161         if( m_eCurrentDriverState != eDriverState_RunningNotDebugging )
1162         {
1163                 SetErrorDescription( MIRSRC( IDS_DRIVER_ERR_DRIVER_STATE_ERROR ) );
1164                 return MIstatus::failure;
1165         }
1166
1167         m_eCurrentDriverState = eDriverState_RunningDebugging;
1168
1169         return MIstatus::success;
1170 }
1171
1172 //++ ------------------------------------------------------------------------------------
1173 // Details: Prepare the client IDE so it will start working/communicating with *this MI 
1174 //                      driver.
1175 // Type:        Method.
1176 // Args:        None.
1177 // Return:      MIstatus::success - Functionality succeeded.
1178 //                      MIstatus::failure - Functionality failed.
1179 // Throws:      None.
1180 //--
1181 bool CMIDriver::InitClientIDEToMIDriver( void ) const
1182 {
1183         // Put other IDE init functions here
1184         return InitClientIDEEclipse();
1185 }
1186
1187 //++ ------------------------------------------------------------------------------------
1188 // Details: The IDE Eclipse when debugging locally expects "(gdb)\n" character
1189 //                      sequence otherwise it refuses to communicate and times out. This should be
1190 //                      sent to Eclipse before anything else.
1191 // Type:        Method.
1192 // Args:        None.
1193 // Return:      MIstatus::success - Functionality succeeded.
1194 //                      MIstatus::failure - Functionality failed.
1195 // Throws:      None.
1196 //--
1197 bool CMIDriver::InitClientIDEEclipse( void ) const
1198 {
1199         std::cout << "(gdb)" << std::endl;
1200
1201         return MIstatus::success;
1202 }
1203
1204 //++ ------------------------------------------------------------------------------------
1205 // Details: Ask *this driver whether it found an executable in the MI Driver's list of 
1206 //                      arguments which to open and debug. If so instigate commands to set up a debug
1207 //                      session for that executable.
1208 // Type:        Method.
1209 // Args:        None.
1210 // Return:      bool - True = True = Yes executable given as one of the parameters to the MI 
1211 //                                 Driver.
1212 //                                 False = not found.
1213 // Throws:      None.
1214 //--
1215 bool CMIDriver::HaveExecutableFileNamePathOnCmdLine( void ) const
1216 {
1217         return m_bHaveExecutableFileNamePathOnCmdLine;
1218 }
1219
1220 //++ ------------------------------------------------------------------------------------
1221 // Details: Retrieve from *this driver executable file name path to start a debug session
1222 //                      with (if present see HaveExecutableFileNamePathOnCmdLine()).
1223 // Type:        Method.
1224 // Args:        None.
1225 // Return:      CMIUtilString & - Executeable file name path or empty string.
1226 // Throws:      None.
1227 //--
1228 const CMIUtilString & CMIDriver::GetExecutableFileNamePathOnCmdLine( void ) const
1229 {
1230         return m_strCmdLineArgExecuteableFileNamePath;
1231 }
1232
1233 //++ ------------------------------------------------------------------------------------
1234 // Details: Execute commands (by injecting them into the stdin line queue container) and
1235 //                      other code to set up the MI Driver such that is can take the executable 
1236 //                      argument passed on the command and create a debug session for it.
1237 // Type:        Method.
1238 // Args:        None.
1239 // Return:      MIstatus::success - Functionality succeeded.
1240 //                      MIstatus::failure - Functionality failed.
1241 // Throws:      None.
1242 //--
1243 bool CMIDriver::LocalDebugSessionStartupInjectCommands( void )
1244 {
1245         const CMIUtilString strCmd( CMIUtilString::Format( "-file-exec-and-symbols %s", m_strCmdLineArgExecuteableFileNamePath.c_str() ) );
1246         
1247         return InjectMICommand( strCmd );
1248 }
1249
1250 //++ ------------------------------------------------------------------------------------
1251 // Details: Set the MI Driver into "its debugging an executable passed as an argument"
1252 //                      mode as against running via a client like Eclipse.
1253 // Type:        Method.
1254 // Args:        None.
1255 // Return:      None.
1256 // Throws:      None.
1257 //--
1258 void CMIDriver::SetDriverDebuggingArgExecutable( void )
1259 {
1260         m_bDriverDebuggingArgExecutable = true;
1261 }
1262
1263 //++ ------------------------------------------------------------------------------------
1264 // Details: Retrieve the MI Driver state indicating if it is operating in "its debugging 
1265 //                      an executable passed as an argument" mode as against running via a client 
1266 //                      like Eclipse.
1267 // Type:        Method.
1268 // Args:        None.
1269 // Return:      None.
1270 // Throws:      None.
1271 //--
1272 bool CMIDriver::IsDriverDebuggingArgExecutable( void ) const
1273 {
1274         return m_bDriverDebuggingArgExecutable;
1275 }
1276