2014-05-16 18:51:01 +08:00
|
|
|
//===-- MIDriverMgr.cpp -----------------------------------------*- C++ -*-===//
|
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
// Third Party Headers:
|
2015-01-20 08:04:26 +08:00
|
|
|
#include "lldb/API/SBError.h"
|
2014-05-16 18:51:01 +08:00
|
|
|
|
|
|
|
// In-house headers:
|
|
|
|
#include "MICmnLog.h"
|
|
|
|
#include "MICmnLogMediumFile.h"
|
2016-09-07 04:57:50 +08:00
|
|
|
#include "MICmnResources.h"
|
2014-05-16 18:51:01 +08:00
|
|
|
#include "MICmnStreamStdout.h"
|
2016-09-07 04:57:50 +08:00
|
|
|
#include "MIDriver.h"
|
|
|
|
#include "MIDriverMgr.h"
|
2014-05-16 18:51:01 +08:00
|
|
|
#include "MIUtilSingletonHelper.h"
|
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
//++
|
|
|
|
//------------------------------------------------------------------------------------
|
2014-11-18 02:06:21 +08:00
|
|
|
// Details: CMIDriverMgr constructor.
|
|
|
|
// Type: Method.
|
|
|
|
// Args: None.
|
|
|
|
// Return: None.
|
|
|
|
// Throws: None.
|
2014-05-16 18:51:01 +08:00
|
|
|
//--
|
2016-09-07 04:57:50 +08:00
|
|
|
CMIDriverMgr::CMIDriverMgr() : m_pDriverCurrent(nullptr), m_bInMi2Mode(false) {}
|
2014-05-16 18:51:01 +08:00
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
//++
|
|
|
|
//------------------------------------------------------------------------------------
|
2014-11-18 02:06:21 +08:00
|
|
|
// Details: CMIDriverMgr destructor.
|
|
|
|
// Type: Overridden.
|
|
|
|
// Args: None.
|
|
|
|
// Return: None.
|
|
|
|
// Throws: None.
|
2014-05-16 18:51:01 +08:00
|
|
|
//--
|
2016-09-07 04:57:50 +08:00
|
|
|
CMIDriverMgr::~CMIDriverMgr() { Shutdown(); }
|
2014-05-16 18:51:01 +08:00
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
//++
|
|
|
|
//------------------------------------------------------------------------------------
|
2014-11-18 02:06:21 +08:00
|
|
|
// Details: Initialize *this manager.
|
|
|
|
// Type: Method.
|
|
|
|
// Args: None.
|
|
|
|
// Return: MIstatus::success - Functional succeeded.
|
|
|
|
// MIstatus::failure - Functional failed.
|
|
|
|
// Throws: None.
|
2014-05-16 18:51:01 +08:00
|
|
|
//--
|
2016-09-07 04:57:50 +08:00
|
|
|
bool CMIDriverMgr::Initialize() {
|
|
|
|
m_clientUsageRefCnt++;
|
2014-11-18 02:06:21 +08:00
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
ClrErrorDescription();
|
2014-11-18 02:06:21 +08:00
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
if (m_bInitialized)
|
|
|
|
return MIstatus::success;
|
2014-11-18 02:06:21 +08:00
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
bool bOk = MIstatus::success;
|
|
|
|
CMIUtilString errMsg;
|
2014-11-18 02:06:21 +08:00
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
// Note initialisation order is important here as some resources depend on
|
|
|
|
// previous
|
|
|
|
MI::ModuleInit<CMICmnLog>(IDS_MI_INIT_ERR_LOG, bOk, errMsg);
|
|
|
|
MI::ModuleInit<CMICmnResources>(IDS_MI_INIT_ERR_RESOURCES, bOk, errMsg);
|
2014-11-18 02:06:21 +08:00
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
m_bInitialized = bOk;
|
2014-11-18 02:06:21 +08:00
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
if (!bOk) {
|
|
|
|
CMIUtilString strInitError(CMIUtilString::Format(
|
|
|
|
MIRSRC(IDS_MI_INIT_ERR_DRIVERMGR), errMsg.c_str()));
|
|
|
|
SetErrorDescription(strInitError);
|
|
|
|
return MIstatus::failure;
|
|
|
|
}
|
2014-11-18 02:06:21 +08:00
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
return bOk;
|
2014-05-16 18:51:01 +08:00
|
|
|
}
|
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
//++
|
|
|
|
//------------------------------------------------------------------------------------
|
|
|
|
// Details: Unbind detach or release resources used by this server in general
|
|
|
|
// common
|
|
|
|
// functionality shared between versions of any server interfaces
|
|
|
|
// implemented.
|
2014-11-18 02:06:21 +08:00
|
|
|
// Type: Method.
|
2016-09-07 04:57:50 +08:00
|
|
|
// Args: vbAppExitOk - (R) True = No problems, false = App exiting with
|
|
|
|
// problems (investigate!).
|
2014-11-18 02:06:21 +08:00
|
|
|
// Return: MIstatus::success - Functional succeeded.
|
|
|
|
// MIstatus::failure - Functional failed.
|
|
|
|
// Throws: None.
|
2014-05-16 18:51:01 +08:00
|
|
|
//--
|
2016-09-07 04:57:50 +08:00
|
|
|
bool CMIDriverMgr::Shutdown() {
|
|
|
|
// Do not want a ref counter because this function needs to be called how ever
|
|
|
|
// this
|
|
|
|
// application stops running
|
|
|
|
// if( --m_clientUsageRefCnt > 0 )
|
|
|
|
// return MIstatus::success;
|
2014-11-18 02:06:21 +08:00
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
ClrErrorDescription();
|
2014-11-18 02:06:21 +08:00
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
if (!m_bInitialized)
|
|
|
|
return MIstatus::success;
|
2014-11-18 02:06:21 +08:00
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
m_bInitialized = false;
|
2014-11-18 02:06:21 +08:00
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
bool bOk = MIstatus::success;
|
|
|
|
CMIUtilString errMsg;
|
2014-11-18 02:06:21 +08:00
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
// Tidy up
|
|
|
|
UnregisterDriverAll();
|
2014-11-18 02:06:21 +08:00
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
// Note shutdown order is important here
|
|
|
|
MI::ModuleShutdown<CMICmnResources>(IDE_MI_SHTDWN_ERR_RESOURCES, bOk, errMsg);
|
|
|
|
MI::ModuleShutdown<CMICmnLog>(IDS_MI_SHTDWN_ERR_LOG, bOk, errMsg);
|
2014-11-18 02:06:21 +08:00
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
if (!bOk) {
|
|
|
|
SetErrorDescriptionn(MIRSRC(IDS_MI_SHTDWN_ERR_DRIVERMGR), errMsg.c_str());
|
|
|
|
}
|
2014-11-18 02:06:21 +08:00
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
return bOk;
|
2014-05-16 18:51:01 +08:00
|
|
|
}
|
2016-09-07 04:57:50 +08:00
|
|
|
//++
|
|
|
|
//------------------------------------------------------------------------------------
|
|
|
|
// Details: Unregister all the Driver registered with *this manager. The manager
|
|
|
|
// also
|
2014-11-18 02:06:21 +08:00
|
|
|
// deletes
|
|
|
|
// Type: Method.
|
|
|
|
// Args: None.
|
|
|
|
// Return: MIstatus::success - Functional succeeded.
|
|
|
|
// MIstatus::failure - Functional failed.
|
|
|
|
// Throws: None.
|
2014-05-16 18:51:01 +08:00
|
|
|
//--
|
2016-09-07 04:57:50 +08:00
|
|
|
bool CMIDriverMgr::UnregisterDriverAll() {
|
|
|
|
MapDriverIdToDriver_t::const_iterator it = m_mapDriverIdToDriver.begin();
|
|
|
|
while (it != m_mapDriverIdToDriver.end()) {
|
|
|
|
IDriver *pDriver = (*it).second;
|
|
|
|
pDriver->DoShutdown();
|
2014-11-18 02:06:21 +08:00
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
// Next
|
|
|
|
++it;
|
|
|
|
}
|
2014-11-18 02:06:21 +08:00
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
m_mapDriverIdToDriver.clear();
|
|
|
|
m_pDriverCurrent = NULL;
|
|
|
|
|
|
|
|
return MIstatus::success;
|
2014-05-16 18:51:01 +08:00
|
|
|
}
|
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
//++
|
|
|
|
//------------------------------------------------------------------------------------
|
|
|
|
// Details: Register a driver with *this Driver Manager. Call
|
|
|
|
// SetUseThisDriverToDoWork()
|
|
|
|
// inform the manager which driver is the one to the work. The manager
|
|
|
|
// calls
|
|
|
|
// the driver's init function which must be successful in order to
|
|
|
|
// complete the
|
2014-11-18 02:06:21 +08:00
|
|
|
// registration.
|
|
|
|
// Type: Method.
|
|
|
|
// Args: vrDriver - (R) The driver to register.
|
|
|
|
// vrDriverID - (R) The driver's ID to lookup by.
|
|
|
|
// Return: MIstatus::success - Functional succeeded.
|
|
|
|
// MIstatus::failure - Functional failed.
|
|
|
|
// Throws: None.
|
2014-05-16 18:51:01 +08:00
|
|
|
//--
|
2016-09-07 04:57:50 +08:00
|
|
|
bool CMIDriverMgr::RegisterDriver(const IDriver &vrDriver,
|
|
|
|
const CMIUtilString &vrDriverID) {
|
|
|
|
if (HaveDriverAlready(vrDriver))
|
|
|
|
return MIstatus::success;
|
2014-11-18 02:06:21 +08:00
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
IDriver *pDriver = const_cast<IDriver *>(&vrDriver);
|
|
|
|
if (!pDriver->SetId(vrDriverID))
|
|
|
|
return MIstatus::failure;
|
|
|
|
if (!pDriver->DoInitialize()) {
|
|
|
|
SetErrorDescriptionn(MIRSRC(IDS_DRIVERMGR_DRIVER_ERR_INIT),
|
|
|
|
pDriver->GetName().c_str(), vrDriverID.c_str(),
|
|
|
|
pDriver->GetError().c_str());
|
|
|
|
return MIstatus::failure;
|
|
|
|
}
|
2014-11-18 02:06:21 +08:00
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
MapPairDriverIdToDriver_t pr(vrDriverID, pDriver);
|
|
|
|
m_mapDriverIdToDriver.insert(pr);
|
|
|
|
|
|
|
|
return MIstatus::success;
|
2014-05-16 18:51:01 +08:00
|
|
|
}
|
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
//++
|
|
|
|
//------------------------------------------------------------------------------------
|
|
|
|
// Details: Query the Driver Manager to see if *this manager has the driver
|
|
|
|
// already
|
2014-11-18 02:06:21 +08:00
|
|
|
// registered.
|
|
|
|
// Type: Method.
|
|
|
|
// Args: vrDriver - (R) The driver to query.
|
|
|
|
// Return: True - registered.
|
|
|
|
// False - not registered.
|
|
|
|
// Throws: None.
|
2014-05-16 18:51:01 +08:00
|
|
|
//--
|
2016-09-07 04:57:50 +08:00
|
|
|
bool CMIDriverMgr::HaveDriverAlready(const IDriver &vrDriver) const {
|
|
|
|
MapDriverIdToDriver_t::const_iterator it = m_mapDriverIdToDriver.begin();
|
|
|
|
while (it != m_mapDriverIdToDriver.end()) {
|
|
|
|
const IDriver *pDrvr = (*it).second;
|
|
|
|
if (pDrvr == &vrDriver)
|
|
|
|
return true;
|
|
|
|
|
|
|
|
// Next
|
|
|
|
++it;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
2014-05-16 18:51:01 +08:00
|
|
|
}
|
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
//++
|
|
|
|
//------------------------------------------------------------------------------------
|
|
|
|
// Details: Unregister a driver from the Driver Manager. Call the
|
|
|
|
// SetUseThisDriverToDoWork()
|
|
|
|
// function to define another driver to do work if the one being
|
|
|
|
// unregistered did
|
2014-11-18 02:06:21 +08:00
|
|
|
// the work previously.
|
|
|
|
// Type: Method.
|
|
|
|
// Args: vrDriver - (R) The driver to unregister.
|
|
|
|
// Return: MIstatus::success - Functional succeeded.
|
|
|
|
// MIstatus::failure - Functional failed.
|
|
|
|
// Throws: None.
|
2014-05-16 18:51:01 +08:00
|
|
|
//--
|
2016-09-07 04:57:50 +08:00
|
|
|
bool CMIDriverMgr::UnregisterDriver(const IDriver &vrDriver) {
|
|
|
|
const IDriver *pDrvr = nullptr;
|
|
|
|
MapDriverIdToDriver_t::const_iterator it = m_mapDriverIdToDriver.begin();
|
|
|
|
while (it != m_mapDriverIdToDriver.end()) {
|
|
|
|
pDrvr = (*it).second;
|
|
|
|
if (pDrvr == &vrDriver)
|
|
|
|
break;
|
|
|
|
|
|
|
|
// Next
|
|
|
|
++it;
|
|
|
|
}
|
|
|
|
m_mapDriverIdToDriver.erase(it);
|
|
|
|
|
|
|
|
if (m_pDriverCurrent == pDrvr)
|
|
|
|
m_pDriverCurrent = nullptr;
|
|
|
|
|
|
|
|
return MIstatus::success;
|
2014-05-16 18:51:01 +08:00
|
|
|
}
|
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
//++
|
|
|
|
//------------------------------------------------------------------------------------
|
|
|
|
// Details: Specify the driver to do work. The Driver Manager drives this
|
|
|
|
// driver. Any
|
|
|
|
// previous driver doing work is not called anymore (so be sure the
|
|
|
|
// previous
|
2014-11-18 02:06:21 +08:00
|
|
|
// driver is in a tidy state before stopping it working).
|
|
|
|
// Type: Method.
|
|
|
|
// Args: vrADriver - (R) A lldb::SBBroadcaster/IDriver derived object.
|
|
|
|
// Return: MIstatus::success - Functional succeeded.
|
|
|
|
// MIstatus::failure - Functional failed.
|
|
|
|
// Throws: None.
|
2014-05-16 18:51:01 +08:00
|
|
|
//--
|
2016-09-07 04:57:50 +08:00
|
|
|
bool CMIDriverMgr::SetUseThisDriverToDoWork(const IDriver &vrADriver) {
|
|
|
|
m_pDriverCurrent = const_cast<IDriver *>(&vrADriver);
|
2014-05-16 18:51:01 +08:00
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
const CMIUtilString msg(
|
|
|
|
CMIUtilString::Format(MIRSRC(IDS_DRIVER_SAY_DRIVER_USING),
|
|
|
|
m_pDriverCurrent->GetName().c_str()));
|
|
|
|
m_pLog->Write(msg, CMICmnLog::eLogVerbosity_Log);
|
2014-05-16 18:51:01 +08:00
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
m_bInMi2Mode = m_pDriverCurrent->GetDriverIsGDBMICompatibleDriver();
|
2014-05-16 18:51:01 +08:00
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
return MIstatus::success;
|
2014-05-16 18:51:01 +08:00
|
|
|
}
|
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
//++
|
|
|
|
//------------------------------------------------------------------------------------
|
2014-11-18 02:06:21 +08:00
|
|
|
// Details: Ask *this manager which driver is currently doing the work.
|
|
|
|
// Type: Method.
|
|
|
|
// Args: None.
|
2016-09-07 04:57:50 +08:00
|
|
|
// Return: IDriver * - Pointer to a driver, NULL if there is no current working
|
|
|
|
// driver.
|
2014-11-18 02:06:21 +08:00
|
|
|
// Throws: None.
|
2014-05-16 18:51:01 +08:00
|
|
|
//--
|
2016-09-07 04:57:50 +08:00
|
|
|
CMIDriverMgr::IDriver *CMIDriverMgr::GetUseThisDriverToDoWork() const {
|
|
|
|
return m_pDriverCurrent;
|
2014-05-16 18:51:01 +08:00
|
|
|
}
|
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
//++
|
|
|
|
//------------------------------------------------------------------------------------
|
2014-11-18 02:06:21 +08:00
|
|
|
// Details: Call this function puts *this driver to work.
|
|
|
|
// Type: Method.
|
|
|
|
// Args: None.
|
|
|
|
// Return: MIstatus::success - Functional succeeded.
|
|
|
|
// MIstatus::failure - Functional failed.
|
|
|
|
// Throws: None.
|
2014-05-16 18:51:01 +08:00
|
|
|
//--
|
2016-09-07 04:57:50 +08:00
|
|
|
bool CMIDriverMgr::DriverMainLoop() {
|
|
|
|
if (m_pDriverCurrent != nullptr) {
|
|
|
|
if (!m_pDriverCurrent->DoMainLoop()) {
|
|
|
|
const CMIUtilString errMsg(
|
|
|
|
CMIUtilString::Format(MIRSRC(IDS_DRIVER_ERR_MAINLOOP),
|
|
|
|
m_pDriverCurrent->GetError().c_str()));
|
|
|
|
CMICmnStreamStdout::Instance().Write(errMsg, true);
|
|
|
|
return MIstatus::failure;
|
2014-11-18 02:06:21 +08:00
|
|
|
}
|
2016-09-07 04:57:50 +08:00
|
|
|
} else {
|
|
|
|
const CMIUtilString errMsg(MIRSRC(IDS_DRIVER_ERR_CURRENT_NOT_SET));
|
|
|
|
CMICmnStreamStdout::Instance().Write(errMsg, true);
|
|
|
|
return MIstatus::failure;
|
|
|
|
}
|
2014-11-18 02:06:21 +08:00
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
return MIstatus::success;
|
2014-05-16 18:51:01 +08:00
|
|
|
}
|
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
//++
|
|
|
|
//------------------------------------------------------------------------------------
|
|
|
|
// Details: Get the current driver to validate executable command line
|
|
|
|
// arguments.
|
2014-11-18 02:06:21 +08:00
|
|
|
// Type: Method.
|
2016-09-07 04:57:50 +08:00
|
|
|
// Args: argc - (R) An integer that contains the count of arguments
|
|
|
|
// that follow in
|
|
|
|
// argv. The argc parameter is always greater than
|
|
|
|
// or equal to 1.
|
|
|
|
// argv - (R) An array of null-terminated strings representing
|
|
|
|
// command-line
|
|
|
|
// arguments entered by the user of the program. By
|
|
|
|
// convention,
|
|
|
|
// argv[0] is the command with which the program is
|
|
|
|
// invoked.
|
2014-11-18 02:06:21 +08:00
|
|
|
// vpStdOut - (R) Point to a standard output stream.
|
2016-09-07 04:57:50 +08:00
|
|
|
// vwbExiting - (W) True = *this want to exit, false = continue to
|
|
|
|
// work.
|
2014-11-18 02:06:21 +08:00
|
|
|
// Return: MIstatus::success - Functional succeeded.
|
|
|
|
// MIstatus::failure - Functional failed.
|
|
|
|
// Throws: None.
|
2014-05-16 18:51:01 +08:00
|
|
|
//--
|
2016-09-07 04:57:50 +08:00
|
|
|
bool CMIDriverMgr::DriverParseArgs(const int argc, const char *argv[],
|
|
|
|
FILE *vpStdOut, bool &vwbExiting) {
|
|
|
|
if (m_pDriverCurrent == nullptr) {
|
|
|
|
const CMIUtilString errMsg(MIRSRC(IDS_DRIVER_ERR_CURRENT_NOT_SET));
|
|
|
|
CMICmnStreamStdout::Instance().Write(errMsg, true);
|
|
|
|
return MIstatus::failure;
|
|
|
|
}
|
|
|
|
|
|
|
|
const lldb::SBError error(
|
|
|
|
m_pDriverCurrent->DoParseArgs(argc, argv, vpStdOut, vwbExiting));
|
|
|
|
bool bOk = !error.Fail();
|
|
|
|
if (!bOk) {
|
|
|
|
CMIUtilString errMsg;
|
|
|
|
const char *pErrorCstr = error.GetCString();
|
|
|
|
if (pErrorCstr != nullptr)
|
|
|
|
errMsg = CMIUtilString::Format(MIRSRC(IDS_DRIVER_ERR_PARSE_ARGS),
|
|
|
|
m_pDriverCurrent->GetName().c_str(),
|
|
|
|
pErrorCstr);
|
|
|
|
else
|
|
|
|
errMsg = CMIUtilString::Format(MIRSRC(IDS_DRIVER_ERR_PARSE_ARGS_UNKNOWN),
|
|
|
|
m_pDriverCurrent->GetName().c_str());
|
2014-11-18 02:06:21 +08:00
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
bOk = CMICmnStreamStdout::Instance().Write(errMsg, true);
|
|
|
|
}
|
2014-11-18 02:06:21 +08:00
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
return bOk;
|
2014-05-16 18:51:01 +08:00
|
|
|
}
|
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
//++
|
|
|
|
//------------------------------------------------------------------------------------
|
2014-11-18 02:06:21 +08:00
|
|
|
// Details: Retrieve the current driver's last error condition.
|
|
|
|
// Type: Method.
|
|
|
|
// Args: None.
|
|
|
|
// Return: CMIUtilString - Text description.
|
|
|
|
// Throws: None.
|
2014-05-16 18:51:01 +08:00
|
|
|
//--
|
2016-09-07 04:57:50 +08:00
|
|
|
CMIUtilString CMIDriverMgr::DriverGetError() const {
|
|
|
|
if (m_pDriverCurrent != nullptr)
|
|
|
|
return m_pDriverCurrent->GetError();
|
|
|
|
else {
|
|
|
|
const CMIUtilString errMsg(MIRSRC(IDS_DRIVER_ERR_CURRENT_NOT_SET));
|
|
|
|
CMICmnStreamStdout::Instance().Write(errMsg, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
return CMIUtilString();
|
2014-05-16 18:51:01 +08:00
|
|
|
}
|
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
//++
|
|
|
|
//------------------------------------------------------------------------------------
|
2014-11-18 02:06:21 +08:00
|
|
|
// Details: Retrieve the current driver's name.
|
|
|
|
// Type: Method.
|
|
|
|
// Args: None.
|
|
|
|
// Return: CMIUtilString - Driver name.
|
|
|
|
// Empty string = no current working driver specified.
|
|
|
|
// Throws: None.
|
2014-05-16 18:51:01 +08:00
|
|
|
//--
|
2016-09-07 04:57:50 +08:00
|
|
|
CMIUtilString CMIDriverMgr::DriverGetName() const {
|
|
|
|
if (m_pDriverCurrent != nullptr)
|
|
|
|
return m_pDriverCurrent->GetName();
|
|
|
|
else {
|
|
|
|
const CMIUtilString errMsg(MIRSRC(IDS_DRIVER_ERR_CURRENT_NOT_SET));
|
|
|
|
CMICmnStreamStdout::Instance().Write(errMsg, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
return CMIUtilString();
|
2014-05-16 18:51:01 +08:00
|
|
|
}
|
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
//++
|
|
|
|
//------------------------------------------------------------------------------------
|
2014-11-18 02:06:21 +08:00
|
|
|
// Details: Retrieve the current driver's debugger object.
|
|
|
|
// Type: Method.
|
|
|
|
// Args: None.
|
|
|
|
// Return: lldb::SBDebugger * - Ptr to driver's debugger object.
|
|
|
|
// - NULL = no current working driver specified.
|
|
|
|
// Throws: None.
|
2014-05-16 18:51:01 +08:00
|
|
|
//--
|
2016-09-07 04:57:50 +08:00
|
|
|
lldb::SBDebugger *CMIDriverMgr::DriverGetTheDebugger() {
|
|
|
|
lldb::SBDebugger *pDebugger = nullptr;
|
|
|
|
if (m_pDriverCurrent != nullptr)
|
|
|
|
pDebugger = &m_pDriverCurrent->GetTheDebugger();
|
|
|
|
else {
|
|
|
|
const CMIUtilString errMsg(MIRSRC(IDS_DRIVER_ERR_CURRENT_NOT_SET));
|
|
|
|
CMICmnStreamStdout::Instance().Write(errMsg, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
return pDebugger;
|
2014-05-16 18:51:01 +08:00
|
|
|
}
|
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
//++
|
|
|
|
//------------------------------------------------------------------------------------
|
|
|
|
// Details: Check the arguments given on the command line. The main purpose of
|
|
|
|
// this
|
|
|
|
// function is to check for the presence of the --interpreter option.
|
|
|
|
// Having
|
|
|
|
// this option present tells *this manager to set the CMIDriver to do
|
|
|
|
// work. If
|
|
|
|
// not use the LLDB driver. The following are options that are only
|
|
|
|
// handled by
|
2014-11-18 02:06:21 +08:00
|
|
|
// the CMIDriverMgr are:
|
|
|
|
// --help or -h
|
|
|
|
// --interpreter
|
|
|
|
// --version
|
|
|
|
// --versionLong
|
2015-02-03 01:08:25 +08:00
|
|
|
// --log
|
2014-11-18 02:06:21 +08:00
|
|
|
// --executable
|
2015-04-23 20:48:42 +08:00
|
|
|
// --log-dir
|
2016-09-07 04:57:50 +08:00
|
|
|
// The above arguments are not handled by any driver object except for
|
|
|
|
// --executable.
|
|
|
|
// The options --interpreter and --executable in code act very similar.
|
|
|
|
// The
|
|
|
|
// --executable is necessary to differentiate whither the MI Driver is
|
|
|
|
// being using
|
|
|
|
// by a client i.e. Eclipse or from the command line. Eclipse issues
|
|
|
|
// the option
|
|
|
|
// --interpreter and also passes additional arguments which can be
|
|
|
|
// interpreted as an
|
|
|
|
// executable if called from the command line. Using --executable tells
|
|
|
|
// the MI
|
|
|
|
// Driver is being called the command line and that the executable
|
|
|
|
// argument is indeed
|
|
|
|
// a specified executable an so actions commands to set up the
|
|
|
|
// executable for a
|
|
|
|
// debug session. Using --interpreter on the command line does not
|
|
|
|
// action additional
|
|
|
|
// commands to initialise a debug session and so be able to launch the
|
|
|
|
// process. The directory
|
2015-04-23 20:48:42 +08:00
|
|
|
// where the log file is created is specified using --log-dir.
|
2014-11-18 02:06:21 +08:00
|
|
|
// Type: Method.
|
2016-09-07 04:57:50 +08:00
|
|
|
// Args: argc - (R) An integer that contains the count of arguments
|
|
|
|
// that follow in
|
|
|
|
// argv. The argc parameter is always greater than
|
|
|
|
// or equal to 1.
|
|
|
|
// argv - (R) An array of null-terminated strings representing
|
|
|
|
// command-line
|
|
|
|
// arguments entered by the user of the program. By
|
|
|
|
// convention,
|
|
|
|
// argv[0] is the command with which the program is
|
|
|
|
// invoked.
|
|
|
|
// vwbExiting - (W) True = *this want to exit, Reasons: help,
|
|
|
|
// invalid arg(s),
|
2014-11-18 02:06:21 +08:00
|
|
|
// version information only.
|
2016-09-07 04:57:50 +08:00
|
|
|
// False = Continue to work, start debugger i.e.
|
|
|
|
// Command
|
2014-11-18 02:06:21 +08:00
|
|
|
// interpreter.
|
|
|
|
// Return: lldb::SBError - LLDB current error status.
|
|
|
|
// Throws: None.
|
2014-05-16 18:51:01 +08:00
|
|
|
//--
|
2016-09-07 04:57:50 +08:00
|
|
|
bool CMIDriverMgr::ParseArgs(const int argc, const char *argv[],
|
|
|
|
bool &vwbExiting) {
|
|
|
|
bool bOk = MIstatus::success;
|
|
|
|
|
|
|
|
vwbExiting = false;
|
|
|
|
|
|
|
|
// Print MI application path to the Log file
|
|
|
|
const CMIUtilString appPath(
|
|
|
|
CMIUtilString::Format(MIRSRC(IDS_MI_APP_FILEPATHNAME), argv[0]));
|
|
|
|
bOk = m_pLog->Write(appPath, CMICmnLog::eLogVerbosity_Log);
|
|
|
|
|
|
|
|
// Print application arguments to the Log file
|
|
|
|
const bool bHaveArgs(argc >= 2);
|
|
|
|
CMIUtilString strArgs(MIRSRC(IDS_MI_APP_ARGS));
|
|
|
|
if (!bHaveArgs) {
|
|
|
|
strArgs += MIRSRC(IDS_WORD_NONE);
|
|
|
|
bOk = bOk && m_pLog->Write(strArgs, CMICmnLog::eLogVerbosity_Log);
|
|
|
|
} else {
|
|
|
|
for (MIint i = 1; i < argc; i++) {
|
|
|
|
strArgs += CMIUtilString::Format("%d:'%s' ", i, argv[i]);
|
2015-04-23 20:48:42 +08:00
|
|
|
}
|
2016-09-07 04:57:50 +08:00
|
|
|
bOk = bOk && m_pLog->Write(strArgs, CMICmnLog::eLogVerbosity_Log);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Look for the command line options
|
|
|
|
bool bHaveArgInterpret = false;
|
|
|
|
bool bHaveArgVersion = false;
|
|
|
|
bool bHaveArgVersionLong = false;
|
|
|
|
bool bHaveArgLog = false;
|
|
|
|
bool bHaveArgLogDir = false;
|
|
|
|
bool bHaveArgHelp = false;
|
|
|
|
CMIUtilString strLogDir;
|
|
|
|
|
|
|
|
bHaveArgInterpret = true;
|
|
|
|
if (bHaveArgs) {
|
|
|
|
// CODETAG_MIDRIVE_CMD_LINE_ARG_HANDLING
|
|
|
|
for (MIint i = 1; i < argc; i++) {
|
|
|
|
// *** Add args to help in GetHelpOnCmdLineArgOptions() ***
|
|
|
|
const CMIUtilString strArg(argv[i]);
|
|
|
|
|
|
|
|
// Argument "--executable" is also check for in CMIDriver::ParseArgs()
|
|
|
|
if ((0 ==
|
|
|
|
strArg.compare(
|
|
|
|
"--interpreter")) || // Given by the client such as Eclipse
|
|
|
|
(0 == strArg.compare("--executable"))) // Used to specify that there
|
|
|
|
// is executable argument also
|
|
|
|
// on the command line
|
|
|
|
{ // See fn description.
|
|
|
|
bHaveArgInterpret = true;
|
|
|
|
}
|
|
|
|
if (0 == strArg.compare("--version")) {
|
|
|
|
bHaveArgVersion = true;
|
|
|
|
}
|
|
|
|
if (0 == strArg.compare("--versionLong")) {
|
|
|
|
bHaveArgVersionLong = true;
|
|
|
|
}
|
|
|
|
if (0 == strArg.compare("--log")) {
|
|
|
|
bHaveArgLog = true;
|
|
|
|
}
|
|
|
|
if (0 == strArg.compare(0, 10, "--log-dir=")) {
|
|
|
|
strLogDir = strArg.substr(10, CMIUtilString::npos);
|
|
|
|
bHaveArgLogDir = true;
|
|
|
|
}
|
|
|
|
if ((0 == strArg.compare("--help")) || (0 == strArg.compare("-h"))) {
|
|
|
|
bHaveArgHelp = true;
|
|
|
|
}
|
2014-11-18 02:06:21 +08:00
|
|
|
}
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
if (bHaveArgLog) {
|
|
|
|
CMICmnLog::Instance().SetEnabled(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (bHaveArgLogDir) {
|
|
|
|
bOk = bOk && CMICmnLogMediumFile::Instance().SetDirectory(strLogDir);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Todo: Remove this output when MI is finished. It is temporary to persuade
|
|
|
|
// Eclipse plugin to work.
|
|
|
|
// Eclipse reads this literally and will not work unless it gets this
|
|
|
|
// exact version text.
|
|
|
|
// Handle --version option (ignore the --interpreter option if present)
|
|
|
|
if (bHaveArgVersion) {
|
|
|
|
vwbExiting = true;
|
|
|
|
bOk = bOk &&
|
|
|
|
CMICmnStreamStdout::Instance().WriteMIResponse(
|
|
|
|
MIRSRC(IDE_MI_VERSION_GDB));
|
|
|
|
return bOk;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Todo: Make this the --version when the above --version version is removed
|
|
|
|
// Handle --versionlong option (ignore the --interpreter option if present)
|
|
|
|
if (bHaveArgVersionLong) {
|
|
|
|
vwbExiting = true;
|
|
|
|
bOk =
|
|
|
|
bOk && CMICmnStreamStdout::Instance().WriteMIResponse(GetAppVersion());
|
|
|
|
return bOk;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Both '--help' and '--interpreter' means give help for MI only. Without
|
|
|
|
// '--interpreter' help the LLDB driver is working and so help is for that.
|
|
|
|
if (bHaveArgHelp && bHaveArgInterpret) {
|
|
|
|
vwbExiting = true;
|
|
|
|
bOk = bOk &&
|
|
|
|
CMICmnStreamStdout::Instance().WriteMIResponse(
|
|
|
|
GetHelpOnCmdLineArgOptions());
|
|
|
|
return bOk;
|
|
|
|
}
|
|
|
|
|
|
|
|
// This makes the assumption that there is at least one MI compatible
|
|
|
|
// driver registered and one LLDB driver registered and the CMIDriver
|
|
|
|
// is the first one found.
|
|
|
|
// ToDo: Implement a better solution that handle any order, any number
|
|
|
|
// of drivers. Or this 'feature' may be removed if deemed not required.
|
|
|
|
IDriver *pLldbDriver = GetFirstNonMIDriver();
|
|
|
|
IDriver *pMi2Driver = GetFirstMIDriver();
|
|
|
|
if (bHaveArgInterpret && (pMi2Driver != nullptr))
|
|
|
|
bOk = bOk && SetUseThisDriverToDoWork(*pMi2Driver);
|
|
|
|
else if (pLldbDriver != nullptr)
|
|
|
|
bOk = bOk && SetUseThisDriverToDoWork(*pLldbDriver);
|
|
|
|
else {
|
|
|
|
if (bOk) {
|
|
|
|
vwbExiting = true;
|
|
|
|
const CMIUtilString msg(MIRSRC(IDS_DRIVER_ERR_NON_REGISTERED));
|
|
|
|
bOk = bOk && CMICmnStreamStdout::Instance().WriteMIResponse(msg);
|
2014-11-18 02:06:21 +08:00
|
|
|
}
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
2014-11-18 02:06:21 +08:00
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
return bOk;
|
2014-05-16 18:51:01 +08:00
|
|
|
}
|
2014-11-18 02:06:21 +08:00
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
//++
|
|
|
|
//------------------------------------------------------------------------------------
|
2014-11-18 02:06:21 +08:00
|
|
|
// Details: Return formatted application version and name information.
|
|
|
|
// Type: Method.
|
|
|
|
// Args: None.
|
|
|
|
// Return: CMIUtilString - Text data.
|
|
|
|
// Throws: None.
|
2014-05-16 18:51:01 +08:00
|
|
|
//--
|
2016-09-07 04:57:50 +08:00
|
|
|
CMIUtilString CMIDriverMgr::GetAppVersion() const {
|
|
|
|
const CMIUtilString strProj(MIRSRC(IDS_PROJNAME));
|
|
|
|
const CMIUtilString strVsn(CMIDriver::Instance().GetVersionDescription());
|
|
|
|
const CMIUtilString strGdb(MIRSRC(IDE_MI_VERSION_GDB));
|
|
|
|
const CMIUtilString strVrsnInfo(CMIUtilString::Format(
|
|
|
|
"%s\n%s\n%s", strProj.c_str(), strVsn.c_str(), strGdb.c_str()));
|
|
|
|
|
|
|
|
return strVrsnInfo;
|
2014-05-16 18:51:01 +08:00
|
|
|
}
|
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
//++
|
|
|
|
//------------------------------------------------------------------------------------
|
|
|
|
// Details: Return formatted help information on all the MI command line
|
|
|
|
// options.
|
2014-11-18 02:06:21 +08:00
|
|
|
// Type: Method.
|
|
|
|
// Args: None.
|
|
|
|
// Return: CMIUtilString - Text data.
|
|
|
|
// Throws: None.
|
2014-05-16 18:51:01 +08:00
|
|
|
//--
|
2016-09-07 04:57:50 +08:00
|
|
|
CMIUtilString CMIDriverMgr::GetHelpOnCmdLineArgOptions() const {
|
|
|
|
const CMIUtilString pHelp[] = {
|
|
|
|
MIRSRC(IDE_MI_APP_DESCRIPTION), MIRSRC(IDE_MI_APP_INFORMATION),
|
|
|
|
MIRSRC(IDE_MI_APP_ARG_USAGE), MIRSRC(IDE_MI_APP_ARG_HELP),
|
|
|
|
MIRSRC(IDE_MI_APP_ARG_VERSION), MIRSRC(IDE_MI_APP_ARG_VERSION_LONG),
|
|
|
|
MIRSRC(IDE_MI_APP_ARG_INTERPRETER), MIRSRC(IDE_MI_APP_ARG_SOURCE),
|
|
|
|
MIRSRC(IDE_MI_APP_ARG_EXECUTEABLE),
|
|
|
|
CMIUtilString::Format(
|
|
|
|
MIRSRC(IDE_MI_APP_ARG_APP_LOG),
|
|
|
|
CMICmnLogMediumFile::Instance().GetFileName().c_str()),
|
|
|
|
MIRSRC(IDE_MI_APP_ARG_APP_LOG_DIR), MIRSRC(IDE_MI_APP_ARG_EXECUTABLE),
|
|
|
|
MIRSRC(IDS_CMD_QUIT_HELP), MIRSRC(IDE_MI_APP_ARG_EXAMPLE)};
|
|
|
|
const MIuint nHelpItems = sizeof pHelp / sizeof pHelp[0];
|
|
|
|
CMIUtilString strHelp;
|
|
|
|
for (MIuint i = 0; i < nHelpItems; i++) {
|
|
|
|
strHelp += pHelp[i];
|
|
|
|
strHelp += "\n\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
return strHelp;
|
2014-05-16 18:51:01 +08:00
|
|
|
}
|
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
//++
|
|
|
|
//------------------------------------------------------------------------------------
|
|
|
|
// Details: Search the registered drivers and return the first driver which says
|
|
|
|
// it is
|
2014-11-18 02:06:21 +08:00
|
|
|
// GDB/MI compatible i.e. the CMIDriver class.
|
|
|
|
// Type: Method.
|
|
|
|
// Args: None.
|
|
|
|
// Return: IDriver * - Ptr to driver, NULL = no driver found.
|
|
|
|
// Throws: None.
|
2014-05-16 18:51:01 +08:00
|
|
|
//--
|
2016-09-07 04:57:50 +08:00
|
|
|
CMIDriverMgr::IDriver *CMIDriverMgr::GetFirstMIDriver() const {
|
|
|
|
IDriver *pDriver = nullptr;
|
|
|
|
MapDriverIdToDriver_t::const_iterator it = m_mapDriverIdToDriver.begin();
|
|
|
|
while (it != m_mapDriverIdToDriver.end()) {
|
|
|
|
const CMIUtilString &rDrvId = (*it).first;
|
|
|
|
MIunused(rDrvId);
|
|
|
|
IDriver *pDvr = (*it).second;
|
|
|
|
if (pDvr->GetDriverIsGDBMICompatibleDriver()) {
|
|
|
|
pDriver = pDvr;
|
|
|
|
break;
|
2014-11-18 02:06:21 +08:00
|
|
|
}
|
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
// Next
|
|
|
|
++it;
|
|
|
|
}
|
|
|
|
|
|
|
|
return pDriver;
|
2014-05-16 18:51:01 +08:00
|
|
|
}
|
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
//++
|
|
|
|
//------------------------------------------------------------------------------------
|
|
|
|
// Details: Search the registered drivers and return the first driver which says
|
|
|
|
// it is
|
2014-11-18 02:06:21 +08:00
|
|
|
// not GDB/MI compatible i.e. the LLDB Driver class.
|
|
|
|
// Type: Method.
|
|
|
|
// Args: None.
|
|
|
|
// Return: IDriver * - Ptr to driver, NULL = no driver found.
|
|
|
|
// Throws: None.
|
2014-05-16 18:51:01 +08:00
|
|
|
//--
|
2016-09-07 04:57:50 +08:00
|
|
|
CMIDriverMgr::IDriver *CMIDriverMgr::GetFirstNonMIDriver() const {
|
|
|
|
IDriver *pDriver = nullptr;
|
|
|
|
MapDriverIdToDriver_t::const_iterator it = m_mapDriverIdToDriver.begin();
|
|
|
|
while (it != m_mapDriverIdToDriver.end()) {
|
|
|
|
const CMIUtilString &rDrvId = (*it).first;
|
|
|
|
MIunused(rDrvId);
|
|
|
|
IDriver *pDvr = (*it).second;
|
|
|
|
if (!pDvr->GetDriverIsGDBMICompatibleDriver()) {
|
|
|
|
pDriver = pDvr;
|
|
|
|
break;
|
2014-11-18 02:06:21 +08:00
|
|
|
}
|
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
// Next
|
|
|
|
++it;
|
|
|
|
}
|
|
|
|
|
|
|
|
return pDriver;
|
2014-05-16 18:51:01 +08:00
|
|
|
}
|
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
//++
|
|
|
|
//------------------------------------------------------------------------------------
|
|
|
|
// Details: Search the registered drivers and return driver with the specified
|
|
|
|
// ID.
|
2014-11-18 02:06:21 +08:00
|
|
|
// Type: Method.
|
|
|
|
// Args: vrDriverId - (R) ID of a driver.
|
|
|
|
// Return: IDriver * - Ptr to driver, NULL = no driver found.
|
|
|
|
// Throws: None.
|
2014-05-16 18:51:01 +08:00
|
|
|
//--
|
2014-11-18 02:06:21 +08:00
|
|
|
CMIDriverMgr::IDriver *
|
2016-09-07 04:57:50 +08:00
|
|
|
CMIDriverMgr::GetDriver(const CMIUtilString &vrDriverId) const {
|
|
|
|
MapDriverIdToDriver_t::const_iterator it =
|
|
|
|
m_mapDriverIdToDriver.find(vrDriverId);
|
|
|
|
if (it == m_mapDriverIdToDriver.end())
|
|
|
|
return nullptr;
|
2014-11-18 02:06:21 +08:00
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
IDriver *pDriver = (*it).second;
|
2014-05-16 18:51:01 +08:00
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
return pDriver;
|
2014-05-16 18:51:01 +08:00
|
|
|
}
|
2015-02-20 18:20:05 +08:00
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
//++
|
|
|
|
//------------------------------------------------------------------------------------
|
|
|
|
// Details: Gets called when lldb-mi gets a signal. Passed signal to current
|
|
|
|
// driver.
|
2015-02-20 18:20:05 +08:00
|
|
|
//
|
|
|
|
// Type: Method.
|
|
|
|
// Args: signal that was delivered
|
|
|
|
// Return: None.
|
|
|
|
// Throws: None.
|
|
|
|
//--
|
2016-09-07 04:57:50 +08:00
|
|
|
void CMIDriverMgr::DeliverSignal(int signal) {
|
|
|
|
if (m_pDriverCurrent != nullptr)
|
|
|
|
m_pDriverCurrent->DeliverSignal(signal);
|
2015-02-20 18:20:05 +08:00
|
|
|
}
|