1 //===-- MICmdBase.cpp -------------------------------------------*- 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 //===----------------------------------------------------------------------===//
11 #include "MICmdBase.h"
12 #include "MICmdArgValConsume.h"
13 #include "MICmdArgValOptionLong.h"
14 #include "MICmnLLDBDebugSessionInfo.h"
15 #include "MICmnMIValueConst.h"
18 //------------------------------------------------------------------------------------
19 // Details: CMICmdBase constructor.
25 CMICmdBase::CMICmdBase()
26 : m_pSelfCreatorFn(nullptr),
27 m_rLLDBDebugSessionInfo(CMICmnLLDBDebugSessionInfo::Instance()),
28 m_bHasResultRecordExtra(false), m_constStrArgThreadGroup("thread-group"),
29 m_constStrArgThread("thread"), m_constStrArgFrame("frame"),
30 m_constStrArgConsume("--"), m_ThreadGrpArgMandatory(false),
31 m_ThreadArgMandatory(false), m_FrameArgMandatory(false) {}
34 //------------------------------------------------------------------------------------
35 // Details: CMICmdBase destructor.
36 // Type: Overrideable.
41 CMICmdBase::~CMICmdBase() {}
44 //------------------------------------------------------------------------------------
45 // Details: The invoker requires this function.
48 // Return: SMICmdData & - *this command's present status/data/information.
51 const SMICmdData &CMICmdBase::GetCmdData() const { return m_cmdData; }
54 //------------------------------------------------------------------------------------
55 // Details: The invoker requires this function.
58 // Return: CMIUtilString & - *this command's current error description.
59 // Empty string indicates command status ok.
62 const CMIUtilString &CMICmdBase::GetErrorDescription() const {
63 return m_strCurrentErrDescription;
67 //------------------------------------------------------------------------------------
68 // Details: The CMICmdFactory requires this function. Retrieve the command and
70 // options description string.
73 // Return: CMIUtilString & - Command description.
76 const CMIUtilString &CMICmdBase::GetMiCmd() const { return m_strMiCmd; }
79 //------------------------------------------------------------------------------------
80 // Details: Help parse the arguments that are common to all commands.
85 void CMICmdBase::AddCommonArgs() {
86 m_setCmdArgs.Add(new CMICmdArgValOptionLong(
87 m_constStrArgThreadGroup, m_ThreadGrpArgMandatory, true,
88 CMICmdArgValListBase::eArgValType_ThreadGrp, 1));
89 m_setCmdArgs.Add(new CMICmdArgValOptionLong(
90 m_constStrArgThread, m_ThreadArgMandatory, true,
91 CMICmdArgValListBase::eArgValType_Number, 1));
93 new CMICmdArgValOptionLong(m_constStrArgFrame, m_FrameArgMandatory, true,
94 CMICmdArgValListBase::eArgValType_Number, 1));
95 m_setCmdArgs.Add(new CMICmdArgValConsume(m_constStrArgConsume, false));
99 //------------------------------------------------------------------------------------
100 // Details: The invoker requires this function. A command must be given working
102 // provide data about its status or provide information to other
109 void CMICmdBase::SetCmdData(const SMICmdData &vCmdData) {
110 m_cmdData = vCmdData;
114 //------------------------------------------------------------------------------------
115 // Details: The command factory requires this function. The factory calls this
117 // so it can obtain *this command's creation function.
120 // Return: CMICmdFactory::CmdCreatorFnPtr - Function pointer.
123 CMICmdFactory::CmdCreatorFnPtr CMICmdBase::GetCmdCreatorFn() const {
124 return m_pSelfCreatorFn;
128 //------------------------------------------------------------------------------------
129 // Details: If a command is an event type (has callbacks registered with
131 // needs to inform the Invoker that it has finished its work so that
133 // Invoker can tidy up and call the commands Acknowledge function (yes
135 // command itself could call the Acknowledge itself but not doing that
142 void CMICmdBase::CmdFinishedTellInvoker() const {
143 CMICmdInvoker::Instance().CmdExecuteFinished(const_cast<CMICmdBase &>(*this));
147 //------------------------------------------------------------------------------------
148 // Details: Returns the final version of the MI result record built up in the
150 // Acknowledge function. The one line text of MI result.
153 // Return: CMIUtilString & - MI text version of the MI result record.
156 const CMIUtilString &CMICmdBase::GetMIResultRecord() const {
157 return m_miResultRecord.GetString();
161 //------------------------------------------------------------------------------------
162 // Details: Retrieve from the command additional MI result to its 1 line
164 // Because of using LLDB additional 'fake'/hack output is sometimes
166 // help the driver client operate i.e. Eclipse.
169 // Return: CMIUtilString & - MI text version of the MI result record.
172 const CMIUtilString &CMICmdBase::GetMIResultRecordExtra() const {
173 return m_miResultRecordExtra;
177 //------------------------------------------------------------------------------------
178 // Details: Hss *this command got additional MI result to its 1 line response.
179 // Because of using LLDB additional 'fake'/hack output is sometimes
181 // help the driver client operate i.e. Eclipse.
184 // Return: bool - True = Yes have additional MI output, false = no nothing
188 bool CMICmdBase::HasMIResultRecordExtra() const {
189 return m_bHasResultRecordExtra;
193 //------------------------------------------------------------------------------------
194 // Details: Short cut function to enter error information into the command's
196 // object and set the command's error status.
198 // Args: rErrMsg - (R) Status description.
202 void CMICmdBase::SetError(const CMIUtilString &rErrMsg) {
203 m_cmdData.bCmdValid = false;
204 m_cmdData.strErrorDescription = rErrMsg;
205 m_cmdData.bCmdExecutedSuccessfully = false;
207 const CMICmnMIValueResult valueResult("msg", CMICmnMIValueConst(rErrMsg));
208 const CMICmnMIResultRecord miResultRecord(
209 m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error,
211 m_miResultRecord = miResultRecord;
212 m_cmdData.strMiCmdResultRecord = miResultRecord.GetString();
216 //------------------------------------------------------------------------------------
217 // Details: Short cut function to check MI command's execute status and
218 // set an error in case of failure.
220 // Args: error - (R) Error description object.
221 // successHandler - (R) function describing actions to execute
222 // in case of success state of passed SBError object.
223 // errorHandler - (R) function describing actions to execute
224 // in case of fail status of passed SBError object.
228 bool CMICmdBase::HandleSBError(const lldb::SBError &error,
229 const std::function<bool()> &successHandler,
230 const std::function<void()> &errorHandler) {
232 return successHandler();
234 SetError(error.GetCString());
236 return MIstatus::failure;
240 //------------------------------------------------------------------------------------
241 // Details: Short cut function to check MI command's execute status and
242 // call specified handler function for success case.
244 // Args: error - (R) Error description object.
245 // successHandler - (R) function describing actions to execute
246 // in case of success state of passed SBError object.
250 bool CMICmdBase::HandleSBErrorWithSuccess(
251 const lldb::SBError &error,
252 const std::function<bool()> &successHandler) {
253 return HandleSBError(error, successHandler);
257 //------------------------------------------------------------------------------------
258 // Details: Short cut function to check MI command's execute status and
259 // call specified handler function for error case.
261 // Args: error - (R) Error description object.
262 // errorHandler - (R) function describing actions to execute
263 // in case of fail status of passed SBError object.
267 bool CMICmdBase::HandleSBErrorWithFailure(
268 const lldb::SBError &error,
269 const std::function<void()> &errorHandler) {
270 return HandleSBError(error, [] { return MIstatus::success; }, errorHandler);
274 //------------------------------------------------------------------------------------
275 // Details: Ask a command to provide its unique identifier.
277 // Args: A unique identifier for this command class.
281 MIuint CMICmdBase::GetGUID() {
282 MIuint64 vptr = reinterpret_cast<MIuint64>(this);
283 MIuint id = (vptr)&0xFFFFFFFF;
284 id ^= (vptr >> 32) & 0xFFFFFFFF;
290 //------------------------------------------------------------------------------------
291 // Details: The invoker requires this function. The parses the command line
293 // arguments to extract values for each of those arguments.
296 // Return: MIstatus::success - Functional succeeded.
297 // MIstatus::failure - Functional failed.
300 bool CMICmdBase::ParseArgs() {
301 // Do nothing - override to implement
303 return MIstatus::success;
307 //------------------------------------------------------------------------------------
308 // Details: Having previously given CMICmdArgSet m_setCmdArgs all the argument
310 // definitions for the command to handle proceed to parse and validate
312 // command's options text for those arguments and extract the values
317 // Return: MIstatus::success - Functional succeeded.
318 // MIstatus::failure - Functional failed.
321 bool CMICmdBase::ParseValidateCmdOptions() {
322 CMICmdArgContext argCntxt(m_cmdData.strMiCmdOption);
323 if (m_setCmdArgs.Validate(m_cmdData.strMiCmd, argCntxt))
324 return MIstatus::success;
326 SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_ARGS),
327 m_cmdData.strMiCmd.c_str(),
328 m_setCmdArgs.GetErrorDescription().c_str()));
330 return MIstatus::failure;
334 //------------------------------------------------------------------------------------
335 // Details: If the MI Driver is not operating via a client i.e. Eclipse but say
337 // on a executable passed in as a argument to the drive then what
339 // do on a command failing? Either continue operating or exit the
341 // Override this function where a command failure cannot allow the
343 // continue operating.
344 // Type: Overrideable.
346 // Return: bool - True = Fatal if command fails, false = can continue if
350 bool CMICmdBase::GetExitAppOnCommandFailure() const { return false; }