Bug Summary

File:tools/lldb/tools/lldb-mi/MIDriver.cpp
Location:line 697, column 9
Description:Value stored to 'bHaveInput' is never read

Annotated Source Code

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