//===-- MICmdBase.h ---------------------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #pragma once // C Includes // C++ Includes #include // for function // Other libraries and framework includes #include "lldb/API/SBError.h" // Project includes #include "MICmdArgSet.h" #include "MICmdData.h" #include "MICmdFactory.h" #include "MICmdInvoker.h" #include "MICmnBase.h" #include "MICmnMIResultRecord.h" #include "MICmnResources.h" #include "MIUtilString.h" // Declarations: class CMICmnLLDBDebugSessionInfo; //++ //============================================================================ // Details: MI command base class. MI commands derive from this base class. // The Command Factory creates command objects and passes them to the // Command Invoker. The Invoker takes ownership of any commands created // which means it is the only object to delete them when a command is // finished working. Commands do not delete themselves. // There are two types of command implicitly defined by the state of // the m_bWaitForEventFromSBDebugger flag. There is the event type // command which registers (command fn) callbacks with the SBListener // does some work then wakes up again when called back, does more work // perhaps, ends, then the Invoker calls the command's Acknowledge // function. The other type of command is one that just does some work, // ends, then the Invoker calls the command's Acknowledge function. No // events set up. // A command's Execute(), Acknowledge() and event callback functions // are // carried out in the main thread. // A command may use the argument derived object classes // (CMICmdArgValBase) // to factor handling and parsing of different types of arguments // presented to a command. A command will produce an error should it // be presented with arguments or options it does not understand. //-- class CMICmdBase : public CMICmnBase, public CMICmdInvoker::ICmd, public CMICmdFactory::ICmd { // Methods: public: CMICmdBase(); // Overridden: // From CMICmdInvoker::ICmd const SMICmdData &GetCmdData() const override; const CMIUtilString &GetErrorDescription() const override; void SetCmdData(const SMICmdData &vCmdData) override; void CmdFinishedTellInvoker() const override; const CMIUtilString &GetMIResultRecord() const override; const CMIUtilString &GetMIResultRecordExtra() const override; bool HasMIResultRecordExtra() const override; bool ParseArgs() override; // From CMICmdFactory::ICmd const CMIUtilString &GetMiCmd() const override; CMICmdFactory::CmdCreatorFnPtr GetCmdCreatorFn() const override; virtual MIuint GetGUID(); void AddCommonArgs(); // Overrideable: ~CMICmdBase() override; virtual bool GetExitAppOnCommandFailure() const; // Methods: protected: void SetError(const CMIUtilString &rErrMsg); bool HandleSBError(const lldb::SBError &error, const std::function &successHandler = [] { return MIstatus::success; }, const std::function &errorHandler = [] {}); bool HandleSBErrorWithSuccess(const lldb::SBError &error, const std::function &successHandler); bool HandleSBErrorWithFailure(const lldb::SBError &error, const std::function &errorHandler); template T *GetOption(const CMIUtilString &vStrOptionName); bool ParseValidateCmdOptions(); // Attributes: CMICmdFactory::CmdCreatorFnPtr m_pSelfCreatorFn; CMIUtilString m_strCurrentErrDescription; // Reason for Execute or Acknowledge // function failure SMICmdData m_cmdData; // Holds information/status of *this command. Used by // other MI code to report or determine state of a // command. bool m_bWaitForEventFromSBDebugger; // True = yes event type command wait, // false = command calls Acknowledge() // straight after Execute() // no waiting CMIUtilString m_strMiCmd; // The MI text identifying *this command i.e. 'break-insert' CMICmnMIResultRecord m_miResultRecord; // This is completed in the // Acknowledge() function and returned // to the Command Invoker to proceed // stdout output. Each command forms 1 response to its input. CMIUtilString m_miResultRecordExtra; // This is completed in the Acknowledge() // function and returned to the Command // Invoker to proceed // stdout output. Hack command produce more response text to help the client // because of using LLDB CMICmnLLDBDebugSessionInfo &m_rLLDBDebugSessionInfo; // Access to command // sharing information or // data across any and // all command based // derived classes. bool m_bHasResultRecordExtra; // True = Yes command produced additional MI // output to its 1 line response, false = no // extra MI output // formed. CMICmdArgSet m_setCmdArgs; // The list of arguments *this command needs to // parse from the options string to carry out work. const CMIUtilString m_constStrArgThreadGroup; const CMIUtilString m_constStrArgThread; const CMIUtilString m_constStrArgFrame; const CMIUtilString m_constStrArgConsume; // These 3 members can be used by the derived classes to make any of // "thread", "frame" or "thread-group" mandatory. bool m_ThreadGrpArgMandatory; bool m_ThreadArgMandatory; bool m_FrameArgMandatory; }; //++ //------------------------------------------------------------------------------------ // Details: Retrieve the command argument or option object pointer so that it // can be // examined. If the option found and valid get the value (number, // string or list // - see CMICmdArgValBase class) from it to use with the command's // decision // making. If the argument is not found the command's error description // is set // describing the error condition. // Type: Template method. // Args: vStrOptionName - (R) The text name of the argument or option to // search for in // the list of the command's possible arguments // or options. // Return: T * - CMICmdArgValBase derived object. // - nullptr = function has failed, unable to retrieve the // option/arg object. // Throws: None. //-- template T *CMICmdBase::GetOption(const CMIUtilString &vStrOptionName) { CMICmdArgValBase *pPtrBase = nullptr; if (!m_setCmdArgs.GetArg(vStrOptionName, pPtrBase)) { SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_OPTION_NOT_FOUND), m_cmdData.strMiCmd.c_str(), vStrOptionName.c_str())); return nullptr; } return static_cast(pPtrBase); } //++ //------------------------------------------------------------------------------------ // Details: Retrieve the command argument or option object pointer using // template function // CMICmdBase::GetOption(). Should the argument (by name) not be found // the // command will exit with a failure (set in GetOption()). // Type: Preprocessor macro. // Args: a - (R) The actual variable's name. // b - (R) The type of variable (appended to CMICmdArgVal i.e. // CMICmdArgValString). // c - (R) The text name of the argument or option to search for in // the list of // the command's possible arguments or options. // Return: T * - CMICmdArgValBase derived object. // - nullptr = function has failed, unable to retrieve the // option/arg object. // Throws: None. //-- #define CMICMDBASE_GETOPTION(a, b, c) \ CMICmdArgVal##b *a = CMICmdBase::GetOption(c); \ if (a == nullptr) \ return MIstatus::failure; // This comment is to stop compile warning for #define