1 //===-- MICmdBase.cpp -------------------------------------------*- 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 //===----------------------------------------------------------------------===//
10 #include "MICmdBase.h"
11 #include "MICmdArgValConsume.h"
12 #include "MICmdArgValOptionLong.h"
13 #include "MICmnLLDBDebugSessionInfo.h"
14 #include "MICmnMIValueConst.h"
17 // Details: CMICmdBase constructor.
23 CMICmdBase::CMICmdBase()
24 : m_pSelfCreatorFn(nullptr),
25 m_rLLDBDebugSessionInfo(CMICmnLLDBDebugSessionInfo::Instance()),
26 m_bHasResultRecordExtra(false), m_constStrArgThreadGroup("thread-group"),
27 m_constStrArgThread("thread"), m_constStrArgFrame("frame"),
28 m_constStrArgConsume("--"), m_ThreadGrpArgMandatory(false),
29 m_ThreadArgMandatory(false), m_FrameArgMandatory(false) {}
32 // Details: CMICmdBase destructor.
33 // Type: Overrideable.
38 CMICmdBase::~CMICmdBase() {}
41 // Details: The invoker requires this function.
44 // Return: SMICmdData & - *this command's present status/data/information.
47 const SMICmdData &CMICmdBase::GetCmdData() const { return m_cmdData; }
50 // Details: The invoker requires this function.
53 // Return: CMIUtilString & - *this command's current error description.
54 // Empty string indicates command status ok.
57 const CMIUtilString &CMICmdBase::GetErrorDescription() const {
58 return m_strCurrentErrDescription;
62 // Details: The CMICmdFactory requires this function. Retrieve the command and
64 // options description string.
67 // Return: CMIUtilString & - Command description.
70 const CMIUtilString &CMICmdBase::GetMiCmd() const { return m_strMiCmd; }
73 // Details: Help parse the arguments that are common to all commands.
78 void CMICmdBase::AddCommonArgs() {
79 m_setCmdArgs.Add(new CMICmdArgValOptionLong(
80 m_constStrArgThreadGroup, m_ThreadGrpArgMandatory, true,
81 CMICmdArgValListBase::eArgValType_ThreadGrp, 1));
82 m_setCmdArgs.Add(new CMICmdArgValOptionLong(
83 m_constStrArgThread, m_ThreadArgMandatory, true,
84 CMICmdArgValListBase::eArgValType_Number, 1));
86 new CMICmdArgValOptionLong(m_constStrArgFrame, m_FrameArgMandatory, true,
87 CMICmdArgValListBase::eArgValType_Number, 1));
88 m_setCmdArgs.Add(new CMICmdArgValConsume(m_constStrArgConsume, false));
92 // Details: The invoker requires this function. A command must be given working
94 // provide data about its status or provide information to other
101 void CMICmdBase::SetCmdData(const SMICmdData &vCmdData) {
102 m_cmdData = vCmdData;
106 // Details: The command factory requires this function. The factory calls this
108 // so it can obtain *this command's creation function.
111 // Return: CMICmdFactory::CmdCreatorFnPtr - Function pointer.
114 CMICmdFactory::CmdCreatorFnPtr CMICmdBase::GetCmdCreatorFn() const {
115 return m_pSelfCreatorFn;
119 // Details: If a command is an event type (has callbacks registered with
121 // needs to inform the Invoker that it has finished its work so that
123 // Invoker can tidy up and call the commands Acknowledge function (yes
125 // command itself could call the Acknowledge itself but not doing that
132 void CMICmdBase::CmdFinishedTellInvoker() const {
133 CMICmdInvoker::Instance().CmdExecuteFinished(const_cast<CMICmdBase &>(*this));
137 // Details: Returns the final version of the MI result record built up in the
139 // Acknowledge function. The one line text of MI result.
142 // Return: CMIUtilString & - MI text version of the MI result record.
145 const CMIUtilString &CMICmdBase::GetMIResultRecord() const {
146 return m_miResultRecord.GetString();
150 // Details: Retrieve from the command additional MI result to its 1 line
152 // Because of using LLDB additional 'fake'/hack output is sometimes
154 // help the driver client operate i.e. Eclipse.
157 // Return: CMIUtilString & - MI text version of the MI result record.
160 const CMIUtilString &CMICmdBase::GetMIResultRecordExtra() const {
161 return m_miResultRecordExtra;
165 // Details: Hss *this command got additional MI result to its 1 line response.
166 // Because of using LLDB additional 'fake'/hack output is sometimes
168 // help the driver client operate i.e. Eclipse.
171 // Return: bool - True = Yes have additional MI output, false = no nothing
175 bool CMICmdBase::HasMIResultRecordExtra() const {
176 return m_bHasResultRecordExtra;
180 // Details: Short cut function to enter error information into the command's
182 // object and set the command's error status.
184 // Args: rErrMsg - (R) Status description.
188 void CMICmdBase::SetError(const CMIUtilString &rErrMsg) {
189 m_cmdData.bCmdValid = false;
190 m_cmdData.strErrorDescription = rErrMsg;
191 m_cmdData.bCmdExecutedSuccessfully = false;
193 const CMICmnMIValueResult valueResult("msg", CMICmnMIValueConst(rErrMsg));
194 const CMICmnMIResultRecord miResultRecord(
195 m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error,
197 m_miResultRecord = miResultRecord;
198 m_cmdData.strMiCmdResultRecord = miResultRecord.GetString();
202 // Details: Short cut function to check MI command's execute status and
203 // set an error in case of failure.
205 // Args: error - (R) Error description object.
206 // successHandler - (R) function describing actions to execute
207 // in case of success state of passed SBError object.
208 // errorHandler - (R) function describing actions to execute
209 // in case of fail status of passed SBError object.
213 bool CMICmdBase::HandleSBError(const lldb::SBError &error,
214 const std::function<bool()> &successHandler,
215 const std::function<void()> &errorHandler) {
217 return successHandler();
219 SetError(error.GetCString());
221 return MIstatus::failure;
225 // Details: Short cut function to check MI command's execute status and
226 // call specified handler function for success case.
228 // Args: error - (R) Error description object.
229 // successHandler - (R) function describing actions to execute
230 // in case of success state of passed SBError object.
234 bool CMICmdBase::HandleSBErrorWithSuccess(
235 const lldb::SBError &error,
236 const std::function<bool()> &successHandler) {
237 return HandleSBError(error, successHandler);
241 // Details: Short cut function to check MI command's execute status and
242 // call specified handler function for error case.
244 // Args: error - (R) Error description object.
245 // errorHandler - (R) function describing actions to execute
246 // in case of fail status of passed SBError object.
250 bool CMICmdBase::HandleSBErrorWithFailure(
251 const lldb::SBError &error,
252 const std::function<void()> &errorHandler) {
253 return HandleSBError(error, [] { return MIstatus::success; }, errorHandler);
257 // Details: Ask a command to provide its unique identifier.
259 // Args: A unique identifier for this command class.
263 MIuint CMICmdBase::GetGUID() {
264 MIuint64 vptr = reinterpret_cast<MIuint64>(this);
265 MIuint id = (vptr)&0xFFFFFFFF;
266 id ^= (vptr >> 32) & 0xFFFFFFFF;
272 // Details: The invoker requires this function. The parses the command line
274 // arguments to extract values for each of those arguments.
277 // Return: MIstatus::success - Functional succeeded.
278 // MIstatus::failure - Functional failed.
281 bool CMICmdBase::ParseArgs() {
282 // Do nothing - override to implement
284 return MIstatus::success;
288 // Details: Having previously given CMICmdArgSet m_setCmdArgs all the argument
290 // definitions for the command to handle proceed to parse and validate
292 // command's options text for those arguments and extract the values
297 // Return: MIstatus::success - Functional succeeded.
298 // MIstatus::failure - Functional failed.
301 bool CMICmdBase::ParseValidateCmdOptions() {
302 CMICmdArgContext argCntxt(m_cmdData.strMiCmdOption);
303 if (m_setCmdArgs.Validate(m_cmdData.strMiCmd, argCntxt))
304 return MIstatus::success;
306 SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_ARGS),
307 m_cmdData.strMiCmd.c_str(),
308 m_setCmdArgs.GetErrorDescription().c_str()));
310 return MIstatus::failure;
314 // Details: If the MI Driver is not operating via a client i.e. Eclipse but say
316 // on a executable passed in as a argument to the drive then what
318 // do on a command failing? Either continue operating or exit the
320 // Override this function where a command failure cannot allow the
322 // continue operating.
323 // Type: Overrideable.
325 // Return: bool - True = Fatal if command fails, false = can continue if
329 bool CMICmdBase::GetExitAppOnCommandFailure() const { return false; }