1 //===-- MICmdBase.h ---------------------------------------------*- 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 //===----------------------------------------------------------------------===//
14 #include <functional> // for function
16 // Other libraries and framework includes
17 #include "lldb/API/SBError.h"
20 #include "MICmdArgSet.h"
21 #include "MICmdData.h"
22 #include "MICmdFactory.h"
23 #include "MICmdInvoker.h"
24 #include "MICmnBase.h"
25 #include "MICmnMIResultRecord.h"
26 #include "MICmnResources.h"
27 #include "MIUtilString.h"
30 class CMICmnLLDBDebugSessionInfo;
33 //============================================================================
34 // Details: MI command base class. MI commands derive from this base class.
35 // The Command Factory creates command objects and passes them to the
36 // Command Invoker. The Invoker takes ownership of any commands created
37 // which means it is the only object to delete them when a command is
38 // finished working. Commands do not delete themselves.
39 // There are two types of command implicitly defined by the state of
40 // the m_bWaitForEventFromSBDebugger flag. There is the event type
41 // command which registers (command fn) callbacks with the SBListener
42 // does some work then wakes up again when called back, does more work
43 // perhaps, ends, then the Invoker calls the command's Acknowledge
44 // function. The other type of command is one that just does some work,
45 // ends, then the Invoker calls the command's Acknowledge function. No
47 // A command's Execute(), Acknowledge() and event callback functions
49 // carried out in the main thread.
50 // A command may use the argument derived object classes
52 // to factor handling and parsing of different types of arguments
53 // presented to a command. A command will produce an error should it
54 // be presented with arguments or options it does not understand.
56 class CMICmdBase : public CMICmnBase,
57 public CMICmdInvoker::ICmd,
58 public CMICmdFactory::ICmd {
64 // From CMICmdInvoker::ICmd
65 const SMICmdData &GetCmdData() const override;
66 const CMIUtilString &GetErrorDescription() const override;
67 void SetCmdData(const SMICmdData &vCmdData) override;
68 void CmdFinishedTellInvoker() const override;
69 const CMIUtilString &GetMIResultRecord() const override;
70 const CMIUtilString &GetMIResultRecordExtra() const override;
71 bool HasMIResultRecordExtra() const override;
72 bool ParseArgs() override;
73 // From CMICmdFactory::ICmd
74 const CMIUtilString &GetMiCmd() const override;
75 CMICmdFactory::CmdCreatorFnPtr GetCmdCreatorFn() const override;
77 virtual MIuint GetGUID();
81 ~CMICmdBase() override;
82 virtual bool GetExitAppOnCommandFailure() const;
86 void SetError(const CMIUtilString &rErrMsg);
87 bool HandleSBError(const lldb::SBError &error,
88 const std::function<bool()> &successHandler =
89 [] { return MIstatus::success; },
90 const std::function<void()> &errorHandler = [] {});
91 bool HandleSBErrorWithSuccess(const lldb::SBError &error,
92 const std::function<bool()> &successHandler);
93 bool HandleSBErrorWithFailure(const lldb::SBError &error,
94 const std::function<void()> &errorHandler);
95 template <class T> T *GetOption(const CMIUtilString &vStrOptionName);
96 bool ParseValidateCmdOptions();
99 CMICmdFactory::CmdCreatorFnPtr m_pSelfCreatorFn;
100 CMIUtilString m_strCurrentErrDescription; // Reason for Execute or Acknowledge
102 SMICmdData m_cmdData; // Holds information/status of *this command. Used by
103 // other MI code to report or determine state of a
105 bool m_bWaitForEventFromSBDebugger; // True = yes event type command wait,
106 // false = command calls Acknowledge()
107 // straight after Execute()
110 m_strMiCmd; // The MI text identifying *this command i.e. 'break-insert'
111 CMICmnMIResultRecord m_miResultRecord; // This is completed in the
112 // Acknowledge() function and returned
113 // to the Command Invoker to proceed
114 // stdout output. Each command forms 1 response to its input.
115 CMIUtilString m_miResultRecordExtra; // This is completed in the Acknowledge()
116 // function and returned to the Command
117 // Invoker to proceed
118 // stdout output. Hack command produce more response text to help the client
119 // because of using LLDB
120 CMICmnLLDBDebugSessionInfo &m_rLLDBDebugSessionInfo; // Access to command
121 // sharing information or
122 // data across any and
125 bool m_bHasResultRecordExtra; // True = Yes command produced additional MI
126 // output to its 1 line response, false = no
129 CMICmdArgSet m_setCmdArgs; // The list of arguments *this command needs to
130 // parse from the options string to carry out work.
131 const CMIUtilString m_constStrArgThreadGroup;
132 const CMIUtilString m_constStrArgThread;
133 const CMIUtilString m_constStrArgFrame;
134 const CMIUtilString m_constStrArgConsume;
136 // These 3 members can be used by the derived classes to make any of
137 // "thread", "frame" or "thread-group" mandatory.
138 bool m_ThreadGrpArgMandatory;
139 bool m_ThreadArgMandatory;
140 bool m_FrameArgMandatory;
144 //------------------------------------------------------------------------------------
145 // Details: Retrieve the command argument or option object pointer so that it
147 // examined. If the option found and valid get the value (number,
149 // - see CMICmdArgValBase class) from it to use with the command's
151 // making. If the argument is not found the command's error description
153 // describing the error condition.
154 // Type: Template method.
155 // Args: vStrOptionName - (R) The text name of the argument or option to
157 // the list of the command's possible arguments
159 // Return: T * - CMICmdArgValBase derived object.
160 // - nullptr = function has failed, unable to retrieve the
161 // option/arg object.
165 T *CMICmdBase::GetOption(const CMIUtilString &vStrOptionName) {
166 CMICmdArgValBase *pPtrBase = nullptr;
167 if (!m_setCmdArgs.GetArg(vStrOptionName, pPtrBase)) {
168 SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_OPTION_NOT_FOUND),
169 m_cmdData.strMiCmd.c_str(),
170 vStrOptionName.c_str()));
174 return static_cast<T *>(pPtrBase);
178 //------------------------------------------------------------------------------------
179 // Details: Retrieve the command argument or option object pointer using
181 // CMICmdBase::GetOption(). Should the argument (by name) not be found
183 // command will exit with a failure (set in GetOption()).
184 // Type: Preprocessor macro.
185 // Args: a - (R) The actual variable's name.
186 // b - (R) The type of variable (appended to CMICmdArgVal i.e.
187 // CMICmdArgValString).
188 // c - (R) The text name of the argument or option to search for in
190 // the command's possible arguments or options.
191 // Return: T * - CMICmdArgValBase derived object.
192 // - nullptr = function has failed, unable to retrieve the
193 // option/arg object.
196 #define CMICMDBASE_GETOPTION(a, b, c) \
197 CMICmdArgVal##b *a = CMICmdBase::GetOption<CMICmdArgVal##b>(c); \
199 return MIstatus::failure;
200 // This comment is to stop compile warning for #define