1 //===-- MIDriverMgr.cpp -----------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
11 // File: MIDriverMgr.cpp
13 // Overview: CMIDriverMgr implementation.
15 // Environment: Compilers: Visual C++ 12.
16 // gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
17 // Libraries: See MIReadmetxt.
22 // Third Party Headers:
23 #include <lldb/API/SBError.h>
26 #include "MIDriverMgr.h"
27 #include "MICmnResources.h"
29 #include "MICmnLogMediumFile.h"
31 #include "MIUtilTermios.h"
32 #include "MICmnStreamStdout.h"
33 #include "MIUtilSingletonHelper.h"
35 //++ ------------------------------------------------------------------------------------
36 // Details: CMIDriverMgr constructor.
42 CMIDriverMgr::CMIDriverMgr( void )
43 : m_pDriverCurrent( nullptr )
44 , m_bInMi2Mode( false )
48 //++ ------------------------------------------------------------------------------------
49 // Details: CMIDriverMgr destructor.
55 CMIDriverMgr::~CMIDriverMgr( void )
60 //++ ------------------------------------------------------------------------------------
61 // Details: Initialize *this manager.
64 // Return: MIstatus::success - Functional succeeded.
65 // MIstatus::failure - Functional failed.
68 bool CMIDriverMgr::Initialize( void )
70 m_clientUsageRefCnt++;
72 ClrErrorDescription();
75 return MIstatus::success;
77 bool bOk = MIstatus::success;
80 // Note initialisation order is important here as some resources depend on previous
81 MI::ModuleInit< CMICmnLog > ( IDS_MI_INIT_ERR_LOG , bOk, errMsg );
82 MI::ModuleInit< CMICmnResources >( IDS_MI_INIT_ERR_RESOURCES, bOk, errMsg );
86 MIUtilTermios::StdinTermiosSet();
93 CMIUtilString strInitError( CMIUtilString::Format( MIRSRC( IDS_MI_INIT_ERR_DRIVERMGR ), errMsg.c_str() ) );
94 SetErrorDescription( strInitError );
95 return MIstatus::failure;
101 //++ ------------------------------------------------------------------------------------
102 // Details: Unbind detach or release resources used by this server in general common
103 // functionality shared between versions of any server interfaces implemented.
105 // Args: vbAppExitOk - (R) True = No problems, false = App exiting with problems (investigate!).
106 // Return: MIstatus::success - Functional succeeded.
107 // MIstatus::failure - Functional failed.
110 bool CMIDriverMgr::Shutdown( void )
112 // Do not want a ref counter because this function needs to be called how ever this
113 // application stops running
114 //if( --m_clientUsageRefCnt > 0 )
115 // return MIstatus::success;
117 bool vbAppExitOk = true;
119 ClrErrorDescription();
121 if( !m_bInitialized )
122 return MIstatus::success;
126 // The MI Driver's log updating may have been switched off switch back on to say all is ok.
127 CMICmnLog::Instance().SetEnabled( true );
129 CMICmnStreamStdout::Instance().Write( MIRSRC( IDE_MI_APP_EXIT_OK ) ); // Both stdout and Log
131 CMICmnLog::WriteLog( MIRSRC( IDE_MI_APP_EXIT_OK ) ); // Just to the Log
136 CMICmnLog & rAppLog = CMICmnLog::Instance();
137 if( rAppLog.GetEnabled() )
139 const CMIUtilString msg( CMIUtilString::Format( MIRSRC( IDE_MI_APP_EXIT_WITH_PROBLEM ), CMICmnLogMediumFile::Instance().GetFileName().c_str() ) );
140 CMICmnStreamStdout::Instance().Write( msg );
144 // The MI Driver's log updating may have been switched off switch back on to say there has been problem.
145 rAppLog.SetEnabled( true );
146 const CMIUtilString msg( CMIUtilString::Format( MIRSRC( IDE_MI_APP_EXIT_WITH_PROBLEM_NO_LOG ), CMICmnLogMediumFile::Instance().GetFileName().c_str() ) );
147 CMICmnStreamStdout::Instance().Write( msg );
151 m_bInitialized = false;
153 bool bOk = MIstatus::success;
154 CMIUtilString errMsg;
157 UnregisterDriverAll();
158 MIUtilTermios::StdinTermiosReset();
160 // Note shutdown order is important here
161 MI::ModuleShutdown< CMICmnResources >( IDE_MI_SHTDWN_ERR_RESOURCES, bOk, errMsg );
162 MI::ModuleShutdown< CMICmnLog > ( IDS_MI_SHTDWN_ERR_LOG , bOk, errMsg );
166 SetErrorDescriptionn( MIRSRC( IDS_MI_SHTDWN_ERR_DRIVERMGR ), errMsg.c_str() );
171 //++ ------------------------------------------------------------------------------------
172 // Details: Unregister all the Driver registered with *this manager. The manager also
176 // Return: MIstatus::success - Functional succeeded.
177 // MIstatus::failure - Functional failed.
180 bool CMIDriverMgr::UnregisterDriverAll( void )
182 MapDriverIdToDriver_t::const_iterator it = m_mapDriverIdToDriver.begin();
183 while( it != m_mapDriverIdToDriver.end() )
185 IDriver * pDriver = (*it).second;
186 pDriver->DoShutdown();
192 m_mapDriverIdToDriver.clear();
193 m_pDriverCurrent = NULL;
195 return MIstatus::success;
198 //++ ------------------------------------------------------------------------------------
199 // Details: Register a driver with *this Driver Manager. Call SetUseThisDriverToDoWork()
200 // inform the manager which driver is the one to the work. The manager calls
201 // the driver's init function which must be successful in order to complete the
204 // Args: vrDriver - (R) The driver to register.
205 // vrDriverID - (R) The driver's ID to lookup by.
206 // Return: MIstatus::success - Functional succeeded.
207 // MIstatus::failure - Functional failed.
210 bool CMIDriverMgr::RegisterDriver( const IDriver & vrDriver, const CMIUtilString & vrDriverID )
212 if( HaveDriverAlready( vrDriver ) )
213 return MIstatus::success;
215 IDriver * pDriver = const_cast< IDriver * >( &vrDriver );
216 if( !pDriver->SetId( vrDriverID ) )
217 return MIstatus::failure;
218 if( !pDriver->DoInitialize() )
220 SetErrorDescriptionn( MIRSRC( IDS_DRIVERMGR_DRIVER_ERR_INIT ), pDriver->GetName().c_str(), vrDriverID.c_str(), pDriver->GetError().c_str() );
221 return MIstatus::failure;
224 MapPairDriverIdToDriver_t pr( vrDriverID, pDriver );
225 m_mapDriverIdToDriver.insert( pr );
227 return MIstatus::success;
230 //++ ------------------------------------------------------------------------------------
231 // Details: Query the Driver Manager to see if *this manager has the driver already
234 // Args: vrDriver - (R) The driver to query.
235 // Return: True - registered.
236 // False - not registered.
239 bool CMIDriverMgr::HaveDriverAlready( const IDriver & vrDriver ) const
241 MapDriverIdToDriver_t::const_iterator it = m_mapDriverIdToDriver.begin();
242 while( it != m_mapDriverIdToDriver.end() )
244 const IDriver * pDrvr = (*it).second;
245 if( pDrvr == &vrDriver )
255 //++ ------------------------------------------------------------------------------------
256 // Details: Unregister a driver from the Driver Manager. Call the SetUseThisDriverToDoWork()
257 // function to define another driver to do work if the one being unregistered did
258 // the work previously.
260 // Args: vrDriver - (R) The driver to unregister.
261 // Return: MIstatus::success - Functional succeeded.
262 // MIstatus::failure - Functional failed.
265 bool CMIDriverMgr::UnregisterDriver( const IDriver & vrDriver )
267 const IDriver * pDrvr = nullptr;
268 MapDriverIdToDriver_t::const_iterator it = m_mapDriverIdToDriver.begin();
269 while( it != m_mapDriverIdToDriver.end() )
271 pDrvr = (*it).second;
272 if( pDrvr == &vrDriver )
278 m_mapDriverIdToDriver.erase( it );
280 if( m_pDriverCurrent == pDrvr )
281 m_pDriverCurrent = nullptr;
283 return MIstatus::success;
286 //++ ------------------------------------------------------------------------------------
287 // Details: Specify the driver to do work. The Driver Manager drives this driver. Any
288 // previous driver doing work is not called anymore (so be sure the previous
289 // driver is in a tidy state before stopping it working).
291 // Args: vrADriver - (R) A lldb::SBBroadcaster/IDriver derived object.
292 // Return: MIstatus::success - Functional succeeded.
293 // MIstatus::failure - Functional failed.
296 bool CMIDriverMgr::SetUseThisDriverToDoWork( const IDriver & vrADriver )
298 m_pDriverCurrent = const_cast< IDriver * >( &vrADriver );
300 const CMIUtilString msg( CMIUtilString::Format( MIRSRC( IDS_DRIVER_SAY_DRIVER_USING ), m_pDriverCurrent->GetName().c_str() ) );
301 m_pLog->Write( msg, CMICmnLog::eLogVerbosity_Log );
303 m_bInMi2Mode = m_pDriverCurrent->GetDriverIsGDBMICompatibleDriver();
305 return MIstatus::success;
308 //++ ------------------------------------------------------------------------------------
309 // Details: Ask *this manager which driver is currently doing the work.
312 // Return: IDriver * - Pointer to a driver, NULL if there is no current working driver.
315 CMIDriverMgr::IDriver * CMIDriverMgr::GetUseThisDriverToDoWork( void ) const
317 return m_pDriverCurrent;
320 //++ ------------------------------------------------------------------------------------
321 // Details: Call this function puts *this driver to work.
324 // Return: MIstatus::success - Functional succeeded.
325 // MIstatus::failure - Functional failed.
328 bool CMIDriverMgr::DriverMainLoop( void )
330 if( m_pDriverCurrent != nullptr )
332 if( !m_pDriverCurrent->DoMainLoop() )
334 const CMIUtilString errMsg( CMIUtilString::Format( MIRSRC( IDS_DRIVER_ERR_MAINLOOP ), m_pDriverCurrent->GetError().c_str() ) );
335 CMICmnStreamStdout::Instance().Write( errMsg, true );
336 return MIstatus::failure;
341 const CMIUtilString errMsg( CMIUtilString::Format( MIRSRC( IDS_DRIVER_ERR_CURRENT_NOT_SET ) ) );
342 CMICmnStreamStdout::Instance().Write( errMsg, true );
343 return MIstatus::failure;
346 return MIstatus::success;
349 //++ ------------------------------------------------------------------------------------
350 // Details: Call *this driver to resize the console window.
352 // Args: vWindowSizeWsCol - (R) New window column size.
353 // Return: MIstatus::success - Functional succeeded.
354 // MIstatus::failure - Functional failed.
357 void CMIDriverMgr::DriverResizeWindow( const uint32_t vWindowSizeWsCol )
359 if( m_pDriverCurrent != nullptr )
360 return m_pDriverCurrent->DoResizeWindow( vWindowSizeWsCol );
363 const CMIUtilString errMsg( CMIUtilString::Format( MIRSRC( IDS_DRIVER_ERR_CURRENT_NOT_SET ) ) );
364 CMICmnStreamStdout::Instance().Write( errMsg, true );
368 //++ ------------------------------------------------------------------------------------
369 // Details: Get the current driver to validate executable command line arguments.
371 // Args: argc - (R) An integer that contains the count of arguments that follow in
372 // argv. The argc parameter is always greater than or equal to 1.
373 // argv - (R) An array of null-terminated strings representing command-line
374 // arguments entered by the user of the program. By convention,
375 // argv[0] is the command with which the program is invoked.
376 // vpStdOut - (R) Point to a standard output stream.
377 // vwbExiting - (W) True = *this want to exit, false = continue to work.
378 // Return: MIstatus::success - Functional succeeded.
379 // MIstatus::failure - Functional failed.
382 bool CMIDriverMgr::DriverParseArgs( const int argc, const char * argv[], FILE * vpStdOut, bool & vwbExiting )
384 if( m_pDriverCurrent == nullptr )
386 const CMIUtilString errMsg( CMIUtilString::Format( MIRSRC( IDS_DRIVER_ERR_CURRENT_NOT_SET ) ) );
387 CMICmnStreamStdout::Instance().Write( errMsg, true );
388 return MIstatus::failure;
391 const lldb::SBError error( m_pDriverCurrent->DoParseArgs( argc, argv, vpStdOut, vwbExiting ) );
392 bool bOk = !error.Fail();
395 CMIUtilString errMsg;
396 const MIchar * pErrorCstr = error.GetCString();
397 if( pErrorCstr != nullptr )
398 errMsg = CMIUtilString::Format( MIRSRC( IDS_DRIVER_ERR_PARSE_ARGS ), m_pDriverCurrent->GetName().c_str(), pErrorCstr );
400 errMsg = CMIUtilString::Format( MIRSRC( IDS_DRIVER_ERR_PARSE_ARGS_UNKNOWN ), m_pDriverCurrent->GetName().c_str() );
402 bOk = CMICmnStreamStdout::Instance().Write( errMsg, true );
408 //++ ------------------------------------------------------------------------------------
409 // Details: Retrieve the current driver's last error condition.
412 // Return: CMIUtilString - Text description.
415 CMIUtilString CMIDriverMgr::DriverGetError( void ) const
417 if( m_pDriverCurrent != nullptr )
418 return m_pDriverCurrent->GetError();
421 const CMIUtilString errMsg( CMIUtilString::Format( MIRSRC( IDS_DRIVER_ERR_CURRENT_NOT_SET ) ) );
422 CMICmnStreamStdout::Instance().Write( errMsg, true );
425 return CMIUtilString();
428 //++ ------------------------------------------------------------------------------------
429 // Details: Retrieve the current driver's name.
432 // Return: CMIUtilString - Driver name.
433 // Empty string = no current working driver specified.
436 CMIUtilString CMIDriverMgr::DriverGetName( void ) const
438 if( m_pDriverCurrent != nullptr )
439 return m_pDriverCurrent->GetName();
442 const CMIUtilString errMsg( CMIUtilString::Format( MIRSRC( IDS_DRIVER_ERR_CURRENT_NOT_SET ) ) );
443 CMICmnStreamStdout::Instance().Write( errMsg, true );
446 return CMIUtilString();
449 //++ ------------------------------------------------------------------------------------
450 // Details: Retrieve the current driver's debugger object.
453 // Return: lldb::SBDebugger * - Ptr to driver's debugger object.
454 // - NULL = no current working driver specified.
457 lldb::SBDebugger * CMIDriverMgr::DriverGetTheDebugger( void )
459 lldb::SBDebugger * pDebugger = nullptr;
460 if( m_pDriverCurrent != nullptr )
461 pDebugger = &m_pDriverCurrent->GetTheDebugger();
464 const CMIUtilString errMsg( CMIUtilString::Format( MIRSRC( IDS_DRIVER_ERR_CURRENT_NOT_SET ) ) );
465 CMICmnStreamStdout::Instance().Write( errMsg, true );
471 //++ ------------------------------------------------------------------------------------
472 // Details: Check the arguments given on the command line. The main purpose of this
473 // function is to check for the presence of the --interpreter option. Having
474 // this option present tells *this manager to set the CMIDriver to do work. If
475 // not use the LLDB driver. The following are options that are only handled by
476 // the CMIDriverMgr are:
483 // The above arguments are not handled by any driver object except for --executable.
484 // The options --interpreter and --executable in code act very similar. The
485 // --executable is necessary to differentiate whither the MI Driver is being using
486 // by a client i.e. Eclipse or from the command line. Eclipse issues the option
487 // --interpreter and also passes additional arguments which can be interpreted as an
488 // executable if called from the command line. Using --executable tells the MI
489 // Driver is being called the command line and that the executable argument is indeed
490 // a specified executable an so actions commands to set up the executable for a
491 // debug session. Using --interpreter on the commnd line does not action additional
492 // commands to initialise a debug session and so be able to launch the process.
494 // Args: argc - (R) An integer that contains the count of arguments that follow in
495 // argv. The argc parameter is always greater than or equal to 1.
496 // argv - (R) An array of null-terminated strings representing command-line
497 // arguments entered by the user of the program. By convention,
498 // argv[0] is the command with which the program is invoked.
499 // vwbExiting - (W) True = *this want to exit, Reasons: help, invalid arg(s),
500 // version information only.
501 // False = Continue to work, start debugger i.e. Command
503 // Return: lldb::SBError - LLDB current error status.
506 bool CMIDriverMgr::ParseArgs( const int argc, const char * argv[], bool & vwbExiting )
508 bool bOk = MIstatus::success;
512 // Print MI application path to the Log file
513 const CMIUtilString appPath( CMIUtilString::Format( MIRSRC( IDS_MI_APP_FILEPATHNAME ), argv[ 0 ] ) );
514 bOk = m_pLog->Write( appPath, CMICmnLog::eLogVerbosity_Log );
516 // Print application arguments to the Log file
517 const bool bHaveArgs( argc >= 2 );
518 CMIUtilString strArgs( MIRSRC( IDS_MI_APP_ARGS ) );
521 strArgs += MIRSRC( IDS_WORD_NONE );
522 bOk = bOk && m_pLog->Write( strArgs, CMICmnLog::eLogVerbosity_Log );
526 for( MIint i = 1; i < argc; i++ )
528 strArgs += CMIUtilString::Format( "%d:'%s' ", i, argv[ i ] );
530 bOk = bOk && m_pLog->Write( strArgs, CMICmnLog::eLogVerbosity_Log );
533 // Look for the command line options
534 bool bHaveArgInterpret = false;
535 bool bHaveArgVersion = false;
536 bool bHaveArgVersionLong = false;
537 bool bHaveArgNoLog = false;
538 bool bHaveArgHelp = false;
540 // Hardcode the use of the MI driver
541 #if MICONFIG_DEFAULT_TO_MI_DRIVER
542 bHaveArgInterpret = true;
543 #endif // MICONFIG_DEFAULT_TO_MI_DRIVER
547 // CODETAG_MIDRIVE_CMD_LINE_ARG_HANDLING
548 for( MIint i = 1; i < argc; i++ )
550 // *** Add args to help in GetHelpOnCmdLineArgOptions() ***
551 const CMIUtilString strArg( argv[ i ] );
553 // Argument "--executable" is also check for in CMIDriver::ParseArgs()
554 if( (0 == strArg.compare( "--interpreter" )) || // Given by the client such as Eclipse
555 (0 == strArg.compare( "--executable" )) ) // Used to specify that there is executable argument also on the command line
556 { // See fn description.
557 bHaveArgInterpret = true;
559 if( 0 == strArg.compare( "--version" ) )
561 bHaveArgVersion = true;
563 if( 0 == strArg.compare( "--versionLong" ) )
565 bHaveArgVersionLong = true;
567 if( 0 == strArg.compare( "--noLog" ) )
569 bHaveArgNoLog = true;
571 if( (0 == strArg.compare( "--help" )) || (0 == strArg.compare( "-h" )) )
580 CMICmnLog::Instance().SetEnabled( false );
583 // Todo: Remove this output when MI is finished. It is temporary to persuade Ecllipse plugin to work.
584 // Eclipse reads this literally and will not work unless it gets this exact version text.
585 // Handle --version option (ignore the --interpreter option if present)
586 if( bHaveArgVersion )
589 bOk = bOk && CMICmnStreamStdout::Instance().WriteMIResponse( MIRSRC( IDE_MI_VERSION_GDB ) );
593 // Todo: Make this the --version when the the above --version version is removed
594 // Handle --versionlong option (ignore the --interpreter option if present)
595 if( bHaveArgVersionLong )
598 bOk = bOk && CMICmnStreamStdout::Instance().WriteMIResponse( GetAppVersion() );
602 // Both '--help' and '--intepreter' means give help for MI only. Without
603 // '--interpreter' help the LLDB driver is working and so help is for that.
604 if( bHaveArgHelp && bHaveArgInterpret )
607 bOk = bOk && CMICmnStreamStdout::Instance().WriteMIResponse( GetHelpOnCmdLineArgOptions() );
611 // This makes the assumption that there is at least one MI compatible
612 // driver registered and one LLDB driver registerd and the CMIDriver
613 // is the first one found.
614 // ToDo: Implement a better solution that handle any order, any number
615 // of drivers. Or this 'feature' may be removed if deemed not required.
616 IDriver * pLldbDriver = GetFirstNonMIDriver();
617 IDriver * pMi2Driver = GetFirstMIDriver();
618 if( bHaveArgInterpret && (pMi2Driver != nullptr) )
619 bOk = bOk && SetUseThisDriverToDoWork( *pMi2Driver );
620 else if( pLldbDriver != nullptr )
621 bOk = bOk && SetUseThisDriverToDoWork( *pLldbDriver );
627 const CMIUtilString msg( MIRSRC( IDS_DRIVER_ERR_NON_REGISTERED ) );
628 bOk = bOk && CMICmnStreamStdout::Instance().WriteMIResponse( msg );
635 //++ ------------------------------------------------------------------------------------
636 // Details: Return formatted application version and name information.
639 // Return: CMIUtilString - Text data.
642 CMIUtilString CMIDriverMgr::GetAppVersion( void ) const
644 const CMIUtilString strProj( MIRSRC( IDS_PROJNAME ) );
645 const CMIUtilString strVsn( CMIDriver::Instance().GetVersionDescription() );
646 const CMIUtilString strGdb( MIRSRC( IDE_MI_VERSION_GDB ) );
647 const CMIUtilString strVrsnInfo( CMIUtilString::Format( "%s\n%s\n%s", strProj.c_str(), strVsn.c_str(), strGdb.c_str() ) );
652 //++ ------------------------------------------------------------------------------------
653 // Details: Return formatted help information on all the MI command line options.
656 // Return: CMIUtilString - Text data.
659 CMIUtilString CMIDriverMgr::GetHelpOnCmdLineArgOptions( void ) const
661 const CMIUtilString pHelp[] =
663 MIRSRC( IDE_MI_APP_DESCRIPTION ),
664 MIRSRC( IDE_MI_APP_INFORMATION ),
665 MIRSRC( IDE_MI_APP_ARG_USAGE ),
666 MIRSRC( IDE_MI_APP_ARG_HELP ),
667 MIRSRC( IDE_MI_APP_ARG_VERSION ),
668 MIRSRC( IDE_MI_APP_ARG_VERSION_LONG ),
669 MIRSRC( IDE_MI_APP_ARG_INTERPRETER ),
670 MIRSRC( IDE_MI_APP_ARG_EXECUTEABLE ),
671 CMIUtilString::Format( MIRSRC( IDE_MI_APP_ARG_NO_APP_LOG ), CMICmnLogMediumFile::Instance().GetFileName().c_str() ),
672 MIRSRC( IDE_MI_APP_ARG_EXECUTABLE ),
673 MIRSRC( IDS_CMD_QUIT_HELP ),
674 MIRSRC( IDE_MI_APP_ARG_EXAMPLE )
676 const MIuint nHelpItems = sizeof pHelp / sizeof pHelp[ 0 ];
677 CMIUtilString strHelp;
678 for( MIuint i = 0; i < nHelpItems; i++ )
680 strHelp += pHelp[ i ];
687 //++ ------------------------------------------------------------------------------------
688 // Details: Search the registered drivers and return the first driver which says it is
689 // GDB/MI compatible i.e. the CMIDriver class.
692 // Return: IDriver * - Ptr to driver, NULL = no driver found.
695 CMIDriverMgr::IDriver * CMIDriverMgr::GetFirstMIDriver( void ) const
697 IDriver * pDriver = nullptr;
698 MapDriverIdToDriver_t::const_iterator it = m_mapDriverIdToDriver.begin();
699 while( it != m_mapDriverIdToDriver.end() )
701 const CMIUtilString & rDrvId = (*it).first; MIunused( rDrvId );
702 IDriver * pDvr = (*it).second;
703 if( pDvr->GetDriverIsGDBMICompatibleDriver() )
716 //++ ------------------------------------------------------------------------------------
717 // Details: Search the registered drivers and return the first driver which says it is
718 // not GDB/MI compatible i.e. the LLDB Driver class.
721 // Return: IDriver * - Ptr to driver, NULL = no driver found.
724 CMIDriverMgr::IDriver * CMIDriverMgr::GetFirstNonMIDriver( void ) const
726 IDriver * pDriver = nullptr;
727 MapDriverIdToDriver_t::const_iterator it = m_mapDriverIdToDriver.begin();
728 while( it != m_mapDriverIdToDriver.end() )
730 const CMIUtilString & rDrvId = (*it).first; MIunused( rDrvId );
731 IDriver * pDvr = (*it).second;
732 if( !pDvr->GetDriverIsGDBMICompatibleDriver() )
745 //++ ------------------------------------------------------------------------------------
746 // Details: Search the registered drivers and return driver with the specified ID.
748 // Args: vrDriverId - (R) ID of a driver.
749 // Return: IDriver * - Ptr to driver, NULL = no driver found.
752 CMIDriverMgr::IDriver * CMIDriverMgr::GetDriver( const CMIUtilString & vrDriverId ) const
754 MapDriverIdToDriver_t::const_iterator it = m_mapDriverIdToDriver.find( vrDriverId );
755 if( it == m_mapDriverIdToDriver.end() )
758 IDriver * pDriver = (*it).second;