1 //===-- MIDriverMgr.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 // Third Party Headers:
11 #include "lldb/API/SBError.h"
12
13 // In-house headers:
14 #include "MICmnLog.h"
15 #include "MICmnLogMediumFile.h"
16 #include "MICmnResources.h"
17 #include "MICmnStreamStdout.h"
18 #include "MIDriver.h"
19 #include "MIDriverMgr.h"
20 #include "MIUtilSingletonHelper.h"
21
22 //++
23 //------------------------------------------------------------------------------------
24 // Details: CMIDriverMgr constructor.
25 // Type: Method.
26 // Args: None.
27 // Return: None.
28 // Throws: None.
29 //--
CMIDriverMgr()30 CMIDriverMgr::CMIDriverMgr() : m_pDriverCurrent(nullptr), m_bInMi2Mode(false) {}
31
32 //++
33 //------------------------------------------------------------------------------------
34 // Details: CMIDriverMgr destructor.
35 // Type: Overridden.
36 // Args: None.
37 // Return: None.
38 // Throws: None.
39 //--
~CMIDriverMgr()40 CMIDriverMgr::~CMIDriverMgr() { Shutdown(); }
41
42 //++
43 //------------------------------------------------------------------------------------
44 // Details: Initialize *this manager.
45 // Type: Method.
46 // Args: None.
47 // Return: MIstatus::success - Functional succeeded.
48 // MIstatus::failure - Functional failed.
49 // Throws: None.
50 //--
Initialize()51 bool CMIDriverMgr::Initialize() {
52 m_clientUsageRefCnt++;
53
54 ClrErrorDescription();
55
56 if (m_bInitialized)
57 return MIstatus::success;
58
59 bool bOk = MIstatus::success;
60 CMIUtilString errMsg;
61
62 // Note initialisation order is important here as some resources depend on
63 // previous
64 MI::ModuleInit<CMICmnLog>(IDS_MI_INIT_ERR_LOG, bOk, errMsg);
65 MI::ModuleInit<CMICmnResources>(IDS_MI_INIT_ERR_RESOURCES, bOk, errMsg);
66
67 m_bInitialized = bOk;
68
69 if (!bOk) {
70 CMIUtilString strInitError(CMIUtilString::Format(
71 MIRSRC(IDS_MI_INIT_ERR_DRIVERMGR), errMsg.c_str()));
72 SetErrorDescription(strInitError);
73 return MIstatus::failure;
74 }
75
76 return bOk;
77 }
78
79 //++
80 //------------------------------------------------------------------------------------
81 // Details: Unbind detach or release resources used by this server in general
82 // common
83 // functionality shared between versions of any server interfaces
84 // implemented.
85 // Type: Method.
86 // Args: vbAppExitOk - (R) True = No problems, false = App exiting with
87 // problems (investigate!).
88 // Return: MIstatus::success - Functional succeeded.
89 // MIstatus::failure - Functional failed.
90 // Throws: None.
91 //--
Shutdown()92 bool CMIDriverMgr::Shutdown() {
93 // Do not want a ref counter because this function needs to be called how ever
94 // this
95 // application stops running
96 // if( --m_clientUsageRefCnt > 0 )
97 // return MIstatus::success;
98
99 ClrErrorDescription();
100
101 if (!m_bInitialized)
102 return MIstatus::success;
103
104 m_bInitialized = false;
105
106 bool bOk = MIstatus::success;
107 CMIUtilString errMsg;
108
109 // Tidy up
110 UnregisterDriverAll();
111
112 // Note shutdown order is important here
113 MI::ModuleShutdown<CMICmnResources>(IDE_MI_SHTDWN_ERR_RESOURCES, bOk, errMsg);
114 MI::ModuleShutdown<CMICmnLog>(IDS_MI_SHTDWN_ERR_LOG, bOk, errMsg);
115
116 if (!bOk) {
117 SetErrorDescriptionn(MIRSRC(IDS_MI_SHTDWN_ERR_DRIVERMGR), errMsg.c_str());
118 }
119
120 return bOk;
121 }
122 //++
123 //------------------------------------------------------------------------------------
124 // Details: Unregister all the Driver registered with *this manager. The manager
125 // also
126 // deletes
127 // Type: Method.
128 // Args: None.
129 // Return: MIstatus::success - Functional succeeded.
130 // MIstatus::failure - Functional failed.
131 // Throws: None.
132 //--
UnregisterDriverAll()133 bool CMIDriverMgr::UnregisterDriverAll() {
134 MapDriverIdToDriver_t::const_iterator it = m_mapDriverIdToDriver.begin();
135 while (it != m_mapDriverIdToDriver.end()) {
136 IDriver *pDriver = (*it).second;
137 pDriver->DoShutdown();
138
139 // Next
140 ++it;
141 }
142
143 m_mapDriverIdToDriver.clear();
144 m_pDriverCurrent = NULL;
145
146 return MIstatus::success;
147 }
148
149 //++
150 //------------------------------------------------------------------------------------
151 // Details: Register a driver with *this Driver Manager. Call
152 // SetUseThisDriverToDoWork()
153 // inform the manager which driver is the one to the work. The manager
154 // calls
155 // the driver's init function which must be successful in order to
156 // complete the
157 // registration.
158 // Type: Method.
159 // Args: vrDriver - (R) The driver to register.
160 // vrDriverID - (R) The driver's ID to lookup by.
161 // Return: MIstatus::success - Functional succeeded.
162 // MIstatus::failure - Functional failed.
163 // Throws: None.
164 //--
RegisterDriver(const IDriver & vrDriver,const CMIUtilString & vrDriverID)165 bool CMIDriverMgr::RegisterDriver(const IDriver &vrDriver,
166 const CMIUtilString &vrDriverID) {
167 if (HaveDriverAlready(vrDriver))
168 return MIstatus::success;
169
170 IDriver *pDriver = const_cast<IDriver *>(&vrDriver);
171 if (!pDriver->SetId(vrDriverID))
172 return MIstatus::failure;
173 if (!pDriver->DoInitialize()) {
174 SetErrorDescriptionn(MIRSRC(IDS_DRIVERMGR_DRIVER_ERR_INIT),
175 pDriver->GetName().c_str(), vrDriverID.c_str(),
176 pDriver->GetError().c_str());
177 return MIstatus::failure;
178 }
179
180 MapPairDriverIdToDriver_t pr(vrDriverID, pDriver);
181 m_mapDriverIdToDriver.insert(pr);
182
183 return MIstatus::success;
184 }
185
186 //++
187 //------------------------------------------------------------------------------------
188 // Details: Query the Driver Manager to see if *this manager has the driver
189 // already
190 // registered.
191 // Type: Method.
192 // Args: vrDriver - (R) The driver to query.
193 // Return: True - registered.
194 // False - not registered.
195 // Throws: None.
196 //--
HaveDriverAlready(const IDriver & vrDriver) const197 bool CMIDriverMgr::HaveDriverAlready(const IDriver &vrDriver) const {
198 MapDriverIdToDriver_t::const_iterator it = m_mapDriverIdToDriver.begin();
199 while (it != m_mapDriverIdToDriver.end()) {
200 const IDriver *pDrvr = (*it).second;
201 if (pDrvr == &vrDriver)
202 return true;
203
204 // Next
205 ++it;
206 }
207
208 return false;
209 }
210
211 //++
212 //------------------------------------------------------------------------------------
213 // Details: Unregister a driver from the Driver Manager. Call the
214 // SetUseThisDriverToDoWork()
215 // function to define another driver to do work if the one being
216 // unregistered did
217 // the work previously.
218 // Type: Method.
219 // Args: vrDriver - (R) The driver to unregister.
220 // Return: MIstatus::success - Functional succeeded.
221 // MIstatus::failure - Functional failed.
222 // Throws: None.
223 //--
UnregisterDriver(const IDriver & vrDriver)224 bool CMIDriverMgr::UnregisterDriver(const IDriver &vrDriver) {
225 const IDriver *pDrvr = nullptr;
226 MapDriverIdToDriver_t::const_iterator it = m_mapDriverIdToDriver.begin();
227 while (it != m_mapDriverIdToDriver.end()) {
228 pDrvr = (*it).second;
229 if (pDrvr == &vrDriver)
230 break;
231
232 // Next
233 ++it;
234 }
235 m_mapDriverIdToDriver.erase(it);
236
237 if (m_pDriverCurrent == pDrvr)
238 m_pDriverCurrent = nullptr;
239
240 return MIstatus::success;
241 }
242
243 //++
244 //------------------------------------------------------------------------------------
245 // Details: Specify the driver to do work. The Driver Manager drives this
246 // driver. Any
247 // previous driver doing work is not called anymore (so be sure the
248 // previous
249 // driver is in a tidy state before stopping it working).
250 // Type: Method.
251 // Args: vrADriver - (R) A lldb::SBBroadcaster/IDriver derived object.
252 // Return: MIstatus::success - Functional succeeded.
253 // MIstatus::failure - Functional failed.
254 // Throws: None.
255 //--
SetUseThisDriverToDoWork(const IDriver & vrADriver)256 bool CMIDriverMgr::SetUseThisDriverToDoWork(const IDriver &vrADriver) {
257 m_pDriverCurrent = const_cast<IDriver *>(&vrADriver);
258
259 const CMIUtilString msg(
260 CMIUtilString::Format(MIRSRC(IDS_DRIVER_SAY_DRIVER_USING),
261 m_pDriverCurrent->GetName().c_str()));
262 m_pLog->Write(msg, CMICmnLog::eLogVerbosity_Log);
263
264 m_bInMi2Mode = m_pDriverCurrent->GetDriverIsGDBMICompatibleDriver();
265
266 return MIstatus::success;
267 }
268
269 //++
270 //------------------------------------------------------------------------------------
271 // Details: Ask *this manager which driver is currently doing the work.
272 // Type: Method.
273 // Args: None.
274 // Return: IDriver * - Pointer to a driver, NULL if there is no current working
275 // driver.
276 // Throws: None.
277 //--
GetUseThisDriverToDoWork() const278 CMIDriverMgr::IDriver *CMIDriverMgr::GetUseThisDriverToDoWork() const {
279 return m_pDriverCurrent;
280 }
281
282 //++
283 //------------------------------------------------------------------------------------
284 // Details: Call this function puts *this driver to work.
285 // Type: Method.
286 // Args: None.
287 // Return: MIstatus::success - Functional succeeded.
288 // MIstatus::failure - Functional failed.
289 // Throws: None.
290 //--
DriverMainLoop()291 bool CMIDriverMgr::DriverMainLoop() {
292 if (m_pDriverCurrent != nullptr) {
293 if (!m_pDriverCurrent->DoMainLoop()) {
294 const CMIUtilString errMsg(
295 CMIUtilString::Format(MIRSRC(IDS_DRIVER_ERR_MAINLOOP),
296 m_pDriverCurrent->GetError().c_str()));
297 CMICmnStreamStdout::Instance().Write(errMsg, true);
298 return MIstatus::failure;
299 }
300 } else {
301 const CMIUtilString errMsg(MIRSRC(IDS_DRIVER_ERR_CURRENT_NOT_SET));
302 CMICmnStreamStdout::Instance().Write(errMsg, true);
303 return MIstatus::failure;
304 }
305
306 return MIstatus::success;
307 }
308
309 //++
310 //------------------------------------------------------------------------------------
311 // Details: Get the current driver to validate executable command line
312 // arguments.
313 // Type: Method.
314 // Args: argc - (R) An integer that contains the count of arguments
315 // that follow in
316 // argv. The argc parameter is always greater than
317 // or equal to 1.
318 // argv - (R) An array of null-terminated strings representing
319 // command-line
320 // arguments entered by the user of the program. By
321 // convention,
322 // argv[0] is the command with which the program is
323 // invoked.
324 // vpStdOut - (R) Point to a standard output stream.
325 // vwbExiting - (W) True = *this want to exit, false = continue to
326 // work.
327 // Return: MIstatus::success - Functional succeeded.
328 // MIstatus::failure - Functional failed.
329 // Throws: None.
330 //--
DriverParseArgs(const int argc,const char * argv[],FILE * vpStdOut,bool & vwbExiting)331 bool CMIDriverMgr::DriverParseArgs(const int argc, const char *argv[],
332 FILE *vpStdOut, bool &vwbExiting) {
333 if (m_pDriverCurrent == nullptr) {
334 const CMIUtilString errMsg(MIRSRC(IDS_DRIVER_ERR_CURRENT_NOT_SET));
335 CMICmnStreamStdout::Instance().Write(errMsg, true);
336 return MIstatus::failure;
337 }
338
339 const lldb::SBError error(
340 m_pDriverCurrent->DoParseArgs(argc, argv, vpStdOut, vwbExiting));
341 bool bOk = !error.Fail();
342 if (!bOk) {
343 CMIUtilString errMsg;
344 const char *pErrorCstr = error.GetCString();
345 if (pErrorCstr != nullptr)
346 errMsg = CMIUtilString::Format(MIRSRC(IDS_DRIVER_ERR_PARSE_ARGS),
347 m_pDriverCurrent->GetName().c_str(),
348 pErrorCstr);
349 else
350 errMsg = CMIUtilString::Format(MIRSRC(IDS_DRIVER_ERR_PARSE_ARGS_UNKNOWN),
351 m_pDriverCurrent->GetName().c_str());
352
353 bOk = CMICmnStreamStdout::Instance().Write(errMsg, true);
354 }
355
356 return bOk;
357 }
358
359 //++
360 //------------------------------------------------------------------------------------
361 // Details: Retrieve the current driver's last error condition.
362 // Type: Method.
363 // Args: None.
364 // Return: CMIUtilString - Text description.
365 // Throws: None.
366 //--
DriverGetError() const367 CMIUtilString CMIDriverMgr::DriverGetError() const {
368 if (m_pDriverCurrent != nullptr)
369 return m_pDriverCurrent->GetError();
370 else {
371 const CMIUtilString errMsg(MIRSRC(IDS_DRIVER_ERR_CURRENT_NOT_SET));
372 CMICmnStreamStdout::Instance().Write(errMsg, true);
373 }
374
375 return CMIUtilString();
376 }
377
378 //++
379 //------------------------------------------------------------------------------------
380 // Details: Retrieve the current driver's name.
381 // Type: Method.
382 // Args: None.
383 // Return: CMIUtilString - Driver name.
384 // Empty string = no current working driver specified.
385 // Throws: None.
386 //--
DriverGetName() const387 CMIUtilString CMIDriverMgr::DriverGetName() const {
388 if (m_pDriverCurrent != nullptr)
389 return m_pDriverCurrent->GetName();
390 else {
391 const CMIUtilString errMsg(MIRSRC(IDS_DRIVER_ERR_CURRENT_NOT_SET));
392 CMICmnStreamStdout::Instance().Write(errMsg, true);
393 }
394
395 return CMIUtilString();
396 }
397
398 //++
399 //------------------------------------------------------------------------------------
400 // Details: Retrieve the current driver's debugger object.
401 // Type: Method.
402 // Args: None.
403 // Return: lldb::SBDebugger * - Ptr to driver's debugger object.
404 // - NULL = no current working driver specified.
405 // Throws: None.
406 //--
DriverGetTheDebugger()407 lldb::SBDebugger *CMIDriverMgr::DriverGetTheDebugger() {
408 lldb::SBDebugger *pDebugger = nullptr;
409 if (m_pDriverCurrent != nullptr)
410 pDebugger = &m_pDriverCurrent->GetTheDebugger();
411 else {
412 const CMIUtilString errMsg(MIRSRC(IDS_DRIVER_ERR_CURRENT_NOT_SET));
413 CMICmnStreamStdout::Instance().Write(errMsg, true);
414 }
415
416 return pDebugger;
417 }
418
419 //++
420 //------------------------------------------------------------------------------------
421 // Details: Check the arguments given on the command line. The main purpose of
422 // this
423 // function is to check for the presence of the --interpreter option.
424 // Having
425 // this option present tells *this manager to set the CMIDriver to do
426 // work. If
427 // not use the LLDB driver. The following are options that are only
428 // handled by
429 // the CMIDriverMgr are:
430 // --help or -h
431 // --interpreter
432 // --version
433 // --versionLong
434 // --log
435 // --executable
436 // --log-dir
437 // The above arguments are not handled by any driver object except for
438 // --executable.
439 // The options --interpreter and --executable in code act very similar.
440 // The
441 // --executable is necessary to differentiate whither the MI Driver is
442 // being using
443 // by a client i.e. Eclipse or from the command line. Eclipse issues
444 // the option
445 // --interpreter and also passes additional arguments which can be
446 // interpreted as an
447 // executable if called from the command line. Using --executable tells
448 // the MI
449 // Driver is being called the command line and that the executable
450 // argument is indeed
451 // a specified executable an so actions commands to set up the
452 // executable for a
453 // debug session. Using --interpreter on the command line does not
454 // action additional
455 // commands to initialise a debug session and so be able to launch the
456 // process. The directory
457 // where the log file is created is specified using --log-dir.
458 // Type: Method.
459 // Args: argc - (R) An integer that contains the count of arguments
460 // that follow in
461 // argv. The argc parameter is always greater than
462 // or equal to 1.
463 // argv - (R) An array of null-terminated strings representing
464 // command-line
465 // arguments entered by the user of the program. By
466 // convention,
467 // argv[0] is the command with which the program is
468 // invoked.
469 // vwbExiting - (W) True = *this want to exit, Reasons: help,
470 // invalid arg(s),
471 // version information only.
472 // False = Continue to work, start debugger i.e.
473 // Command
474 // interpreter.
475 // Return: lldb::SBError - LLDB current error status.
476 // Throws: None.
477 //--
ParseArgs(const int argc,const char * argv[],bool & vwbExiting)478 bool CMIDriverMgr::ParseArgs(const int argc, const char *argv[],
479 bool &vwbExiting) {
480 bool bOk = MIstatus::success;
481
482 vwbExiting = false;
483
484 // Print MI application path to the Log file
485 const CMIUtilString appPath(
486 CMIUtilString::Format(MIRSRC(IDS_MI_APP_FILEPATHNAME), argv[0]));
487 bOk = m_pLog->Write(appPath, CMICmnLog::eLogVerbosity_Log);
488
489 // Print application arguments to the Log file
490 const bool bHaveArgs(argc >= 2);
491 CMIUtilString strArgs(MIRSRC(IDS_MI_APP_ARGS));
492 if (!bHaveArgs) {
493 strArgs += MIRSRC(IDS_WORD_NONE);
494 bOk = bOk && m_pLog->Write(strArgs, CMICmnLog::eLogVerbosity_Log);
495 } else {
496 for (MIint i = 1; i < argc; i++) {
497 strArgs += CMIUtilString::Format("%d:'%s' ", i, argv[i]);
498 }
499 bOk = bOk && m_pLog->Write(strArgs, CMICmnLog::eLogVerbosity_Log);
500 }
501
502 // Look for the command line options
503 bool bHaveArgInterpret = false;
504 bool bHaveArgVersion = false;
505 bool bHaveArgVersionLong = false;
506 bool bHaveArgLog = false;
507 bool bHaveArgLogDir = false;
508 bool bHaveArgHelp = false;
509 CMIUtilString strLogDir;
510
511 bHaveArgInterpret = true;
512 if (bHaveArgs) {
513 // CODETAG_MIDRIVE_CMD_LINE_ARG_HANDLING
514 for (MIint i = 1; i < argc; i++) {
515 // *** Add args to help in GetHelpOnCmdLineArgOptions() ***
516 const CMIUtilString strArg(argv[i]);
517
518 // Argument "--executable" is also check for in CMIDriver::ParseArgs()
519 if (("--interpreter" == strArg) || // Given by the client such as Eclipse
520 ("--executable" == strArg)) // Used to specify that there
521 // is executable argument also
522 // on the command line
523 { // See fn description.
524 bHaveArgInterpret = true;
525 }
526 if ("--version" == strArg) {
527 bHaveArgVersion = true;
528 }
529 if ("--versionLong" == strArg) {
530 bHaveArgVersionLong = true;
531 }
532 if ("--log" == strArg) {
533 bHaveArgLog = true;
534 }
535 if (0 == strArg.compare(0, 10, "--log-dir=")) {
536 strLogDir = strArg.substr(10, CMIUtilString::npos);
537 bHaveArgLogDir = true;
538 }
539 if (("--help" == strArg) || ("-h" == strArg)) {
540 bHaveArgHelp = true;
541 }
542 }
543 }
544
545 if (bHaveArgLog) {
546 CMICmnLog::Instance().SetEnabled(true);
547 }
548
549 if (bHaveArgLogDir) {
550 bOk = bOk && CMICmnLogMediumFile::Instance().SetDirectory(strLogDir);
551 }
552
553 // Todo: Remove this output when MI is finished. It is temporary to persuade
554 // Eclipse plugin to work.
555 // Eclipse reads this literally and will not work unless it gets this
556 // exact version text.
557 // Handle --version option (ignore the --interpreter option if present)
558 if (bHaveArgVersion) {
559 vwbExiting = true;
560 bOk = bOk &&
561 CMICmnStreamStdout::Instance().WriteMIResponse(
562 MIRSRC(IDE_MI_VERSION_GDB));
563 return bOk;
564 }
565
566 // Todo: Make this the --version when the above --version version is removed
567 // Handle --versionlong option (ignore the --interpreter option if present)
568 if (bHaveArgVersionLong) {
569 vwbExiting = true;
570 bOk =
571 bOk && CMICmnStreamStdout::Instance().WriteMIResponse(GetAppVersion());
572 return bOk;
573 }
574
575 // Both '--help' and '--interpreter' means give help for MI only. Without
576 // '--interpreter' help the LLDB driver is working and so help is for that.
577 if (bHaveArgHelp && bHaveArgInterpret) {
578 vwbExiting = true;
579 bOk = bOk &&
580 CMICmnStreamStdout::Instance().WriteMIResponse(
581 GetHelpOnCmdLineArgOptions());
582 return bOk;
583 }
584
585 // This makes the assumption that there is at least one MI compatible
586 // driver registered and one LLDB driver registered and the CMIDriver
587 // is the first one found.
588 // ToDo: Implement a better solution that handle any order, any number
589 // of drivers. Or this 'feature' may be removed if deemed not required.
590 IDriver *pLldbDriver = GetFirstNonMIDriver();
591 IDriver *pMi2Driver = GetFirstMIDriver();
592 if (bHaveArgInterpret && (pMi2Driver != nullptr))
593 bOk = bOk && SetUseThisDriverToDoWork(*pMi2Driver);
594 else if (pLldbDriver != nullptr)
595 bOk = bOk && SetUseThisDriverToDoWork(*pLldbDriver);
596 else {
597 if (bOk) {
598 vwbExiting = true;
599 const CMIUtilString msg(MIRSRC(IDS_DRIVER_ERR_NON_REGISTERED));
600 bOk = bOk && CMICmnStreamStdout::Instance().WriteMIResponse(msg);
601 }
602 }
603
604 return bOk;
605 }
606
607 //++
608 //------------------------------------------------------------------------------------
609 // Details: Return formatted application version and name information.
610 // Type: Method.
611 // Args: None.
612 // Return: CMIUtilString - Text data.
613 // Throws: None.
614 //--
GetAppVersion() const615 CMIUtilString CMIDriverMgr::GetAppVersion() const {
616 const CMIUtilString strProj(MIRSRC(IDS_PROJNAME));
617 const CMIUtilString strVsn(CMIDriver::Instance().GetVersionDescription());
618 const CMIUtilString strGdb(MIRSRC(IDE_MI_VERSION_GDB));
619 const CMIUtilString strVrsnInfo(CMIUtilString::Format(
620 "%s\n%s\n%s", strProj.c_str(), strVsn.c_str(), strGdb.c_str()));
621
622 return strVrsnInfo;
623 }
624
625 //++
626 //------------------------------------------------------------------------------------
627 // Details: Return formatted help information on all the MI command line
628 // options.
629 // Type: Method.
630 // Args: None.
631 // Return: CMIUtilString - Text data.
632 // Throws: None.
633 //--
GetHelpOnCmdLineArgOptions() const634 CMIUtilString CMIDriverMgr::GetHelpOnCmdLineArgOptions() const {
635 const CMIUtilString pHelp[] = {
636 MIRSRC(IDE_MI_APP_DESCRIPTION), MIRSRC(IDE_MI_APP_INFORMATION),
637 MIRSRC(IDE_MI_APP_ARG_USAGE), MIRSRC(IDE_MI_APP_ARG_HELP),
638 MIRSRC(IDE_MI_APP_ARG_VERSION), MIRSRC(IDE_MI_APP_ARG_VERSION_LONG),
639 MIRSRC(IDE_MI_APP_ARG_INTERPRETER), MIRSRC(IDE_MI_APP_ARG_SOURCE),
640 MIRSRC(IDE_MI_APP_ARG_EXECUTEABLE),
641 MIRSRC(IDE_MI_APP_ARG_SYNCHRONOUS),
642 CMIUtilString::Format(
643 MIRSRC(IDE_MI_APP_ARG_APP_LOG),
644 CMICmnLogMediumFile::Instance().GetFileName().c_str()),
645 MIRSRC(IDE_MI_APP_ARG_APP_LOG_DIR), MIRSRC(IDE_MI_APP_ARG_EXECUTABLE),
646 MIRSRC(IDS_CMD_QUIT_HELP), MIRSRC(IDE_MI_APP_ARG_EXAMPLE)};
647 const MIuint nHelpItems = sizeof pHelp / sizeof pHelp[0];
648 CMIUtilString strHelp;
649 for (MIuint i = 0; i < nHelpItems; i++) {
650 strHelp += pHelp[i];
651 strHelp += "\n\n";
652 }
653
654 return strHelp;
655 }
656
657 //++
658 //------------------------------------------------------------------------------------
659 // Details: Search the registered drivers and return the first driver which says
660 // it is
661 // GDB/MI compatible i.e. the CMIDriver class.
662 // Type: Method.
663 // Args: None.
664 // Return: IDriver * - Ptr to driver, NULL = no driver found.
665 // Throws: None.
666 //--
GetFirstMIDriver() const667 CMIDriverMgr::IDriver *CMIDriverMgr::GetFirstMIDriver() const {
668 IDriver *pDriver = nullptr;
669 MapDriverIdToDriver_t::const_iterator it = m_mapDriverIdToDriver.begin();
670 while (it != m_mapDriverIdToDriver.end()) {
671 const CMIUtilString &rDrvId = (*it).first;
672 MIunused(rDrvId);
673 IDriver *pDvr = (*it).second;
674 if (pDvr->GetDriverIsGDBMICompatibleDriver()) {
675 pDriver = pDvr;
676 break;
677 }
678
679 // Next
680 ++it;
681 }
682
683 return pDriver;
684 }
685
686 //++
687 //------------------------------------------------------------------------------------
688 // Details: Search the registered drivers and return the first driver which says
689 // it is
690 // not GDB/MI compatible i.e. the LLDB Driver class.
691 // Type: Method.
692 // Args: None.
693 // Return: IDriver * - Ptr to driver, NULL = no driver found.
694 // Throws: None.
695 //--
GetFirstNonMIDriver() const696 CMIDriverMgr::IDriver *CMIDriverMgr::GetFirstNonMIDriver() const {
697 IDriver *pDriver = nullptr;
698 MapDriverIdToDriver_t::const_iterator it = m_mapDriverIdToDriver.begin();
699 while (it != m_mapDriverIdToDriver.end()) {
700 const CMIUtilString &rDrvId = (*it).first;
701 MIunused(rDrvId);
702 IDriver *pDvr = (*it).second;
703 if (!pDvr->GetDriverIsGDBMICompatibleDriver()) {
704 pDriver = pDvr;
705 break;
706 }
707
708 // Next
709 ++it;
710 }
711
712 return pDriver;
713 }
714
715 //++
716 //------------------------------------------------------------------------------------
717 // Details: Search the registered drivers and return driver with the specified
718 // ID.
719 // Type: Method.
720 // Args: vrDriverId - (R) ID of a driver.
721 // Return: IDriver * - Ptr to driver, NULL = no driver found.
722 // Throws: None.
723 //--
724 CMIDriverMgr::IDriver *
GetDriver(const CMIUtilString & vrDriverId) const725 CMIDriverMgr::GetDriver(const CMIUtilString &vrDriverId) const {
726 MapDriverIdToDriver_t::const_iterator it =
727 m_mapDriverIdToDriver.find(vrDriverId);
728 if (it == m_mapDriverIdToDriver.end())
729 return nullptr;
730
731 IDriver *pDriver = (*it).second;
732
733 return pDriver;
734 }
735
736 //++
737 //------------------------------------------------------------------------------------
738 // Details: Gets called when lldb-mi gets a signal. Passed signal to current
739 // driver.
740 //
741 // Type: Method.
742 // Args: signal that was delivered
743 // Return: None.
744 // Throws: None.
745 //--
DeliverSignal(int signal)746 void CMIDriverMgr::DeliverSignal(int signal) {
747 if (m_pDriverCurrent != nullptr)
748 m_pDriverCurrent->DeliverSignal(signal);
749 }
750