1 //===-- MICmdBase.h ---------------------------------------------*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
13 #include "lldb/API/SBError.h"
15 #include "MICmdArgSet.h"
16 #include "MICmdData.h"
17 #include "MICmdFactory.h"
18 #include "MICmdInvoker.h"
19 #include "MICmnBase.h"
20 #include "MICmnMIResultRecord.h"
21 #include "MICmnResources.h"
22 #include "MIUtilString.h"
25 class CMICmnLLDBDebugSessionInfo;
28 //============================================================================
29 // Details: MI command base class. MI commands derive from this base class.
30 // The Command Factory creates command objects and passes them to the
31 // Command Invoker. The Invoker takes ownership of any commands created
32 // which means it is the only object to delete them when a command is
33 // finished working. Commands do not delete themselves.
34 // There are two types of command implicitly defined by the state of
35 // the m_bWaitForEventFromSBDebugger flag. There is the event type
36 // command which registers (command fn) callbacks with the SBListener
37 // does some work then wakes up again when called back, does more work
38 // perhaps, ends, then the Invoker calls the command's Acknowledge
39 // function. The other type of command is one that just does some work,
40 // ends, then the Invoker calls the command's Acknowledge function. No
42 // A command's Execute(), Acknowledge() and event callback functions
44 // carried out in the main thread.
45 // A command may use the argument derived object classes
47 // to factor handling and parsing of different types of arguments
48 // presented to a command. A command will produce an error should it
49 // be presented with arguments or options it does not understand.
51 class CMICmdBase : public CMICmnBase,
52 public CMICmdInvoker::ICmd,
53 public CMICmdFactory::ICmd {
59 // From CMICmdInvoker::ICmd
60 const SMICmdData &GetCmdData() const override;
61 const CMIUtilString &GetErrorDescription() const override;
62 void SetCmdData(const SMICmdData &vCmdData) override;
63 void CmdFinishedTellInvoker() const override;
64 const CMIUtilString &GetMIResultRecord() const override;
65 const CMIUtilString &GetMIResultRecordExtra() const override;
66 bool HasMIResultRecordExtra() const override;
67 bool ParseArgs() override;
68 // From CMICmdFactory::ICmd
69 const CMIUtilString &GetMiCmd() const override;
70 CMICmdFactory::CmdCreatorFnPtr GetCmdCreatorFn() const override;
72 virtual MIuint GetGUID();
76 ~CMICmdBase() override;
77 virtual bool GetExitAppOnCommandFailure() const;
81 void SetError(const CMIUtilString &rErrMsg);
82 bool HandleSBError(const lldb::SBError &error,
83 const std::function<bool()> &successHandler =
84 [] { return MIstatus::success; },
85 const std::function<void()> &errorHandler = [] {});
86 bool HandleSBErrorWithSuccess(const lldb::SBError &error,
87 const std::function<bool()> &successHandler);
88 bool HandleSBErrorWithFailure(const lldb::SBError &error,
89 const std::function<void()> &errorHandler);
90 template <class T> T *GetOption(const CMIUtilString &vStrOptionName);
91 bool ParseValidateCmdOptions();
94 CMICmdFactory::CmdCreatorFnPtr m_pSelfCreatorFn;
95 CMIUtilString m_strCurrentErrDescription; // Reason for Execute or Acknowledge
97 SMICmdData m_cmdData; // Holds information/status of *this command. Used by
98 // other MI code to report or determine state of a
100 bool m_bWaitForEventFromSBDebugger; // True = yes event type command wait,
101 // false = command calls Acknowledge()
102 // straight after Execute()
105 m_strMiCmd; // The MI text identifying *this command i.e. 'break-insert'
106 CMICmnMIResultRecord m_miResultRecord; // This is completed in the
107 // Acknowledge() function and returned
108 // to the Command Invoker to proceed
109 // stdout output. Each command forms 1 response to its input.
110 CMIUtilString m_miResultRecordExtra; // This is completed in the Acknowledge()
111 // function and returned to the Command
112 // Invoker to proceed
113 // stdout output. Hack command produce more response text to help the client
114 // because of using LLDB
115 CMICmnLLDBDebugSessionInfo &m_rLLDBDebugSessionInfo; // Access to command
116 // sharing information or
117 // data across any and
120 bool m_bHasResultRecordExtra; // True = Yes command produced additional MI
121 // output to its 1 line response, false = no
124 CMICmdArgSet m_setCmdArgs; // The list of arguments *this command needs to
125 // parse from the options string to carry out work.
126 const CMIUtilString m_constStrArgThreadGroup;
127 const CMIUtilString m_constStrArgThread;
128 const CMIUtilString m_constStrArgFrame;
129 const CMIUtilString m_constStrArgConsume;
131 // These 3 members can be used by the derived classes to make any of
132 // "thread", "frame" or "thread-group" mandatory.
133 bool m_ThreadGrpArgMandatory;
134 bool m_ThreadArgMandatory;
135 bool m_FrameArgMandatory;
139 // Details: Retrieve the command argument or option object pointer so that it
141 // examined. If the option found and valid get the value (number,
143 // - see CMICmdArgValBase class) from it to use with the command's
145 // making. If the argument is not found the command's error description
147 // describing the error condition.
148 // Type: Template method.
149 // Args: vStrOptionName - (R) The text name of the argument or option to
151 // the list of the command's possible arguments
153 // Return: T * - CMICmdArgValBase derived object.
154 // - nullptr = function has failed, unable to retrieve the
155 // option/arg object.
159 T *CMICmdBase::GetOption(const CMIUtilString &vStrOptionName) {
160 CMICmdArgValBase *pPtrBase = nullptr;
161 if (!m_setCmdArgs.GetArg(vStrOptionName, pPtrBase)) {
162 SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_OPTION_NOT_FOUND),
163 m_cmdData.strMiCmd.c_str(),
164 vStrOptionName.c_str()));
168 return static_cast<T *>(pPtrBase);
172 // Details: Retrieve the command argument or option object pointer using
174 // CMICmdBase::GetOption(). Should the argument (by name) not be found
176 // command will exit with a failure (set in GetOption()).
177 // Type: Preprocessor macro.
178 // Args: a - (R) The actual variable's name.
179 // b - (R) The type of variable (appended to CMICmdArgVal i.e.
180 // CMICmdArgValString).
181 // c - (R) The text name of the argument or option to search for in
183 // the command's possible arguments or options.
184 // Return: T * - CMICmdArgValBase derived object.
185 // - nullptr = function has failed, unable to retrieve the
186 // option/arg object.
189 #define CMICMDBASE_GETOPTION(a, b, c) \
190 CMICmdArgVal##b *a = CMICmdBase::GetOption<CMICmdArgVal##b>(c); \
192 return MIstatus::failure;
193 // This comment is to stop compile warning for #define