]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/tools/lldb-mi/MICmdBase.cpp
MFV r348568: 9466 add JSON output support to channel programs
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / tools / lldb-mi / MICmdBase.cpp
1 //===-- MICmdBase.cpp -------------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 // In-house headers:
11 #include "MICmdBase.h"
12 #include "MICmdArgValConsume.h"
13 #include "MICmdArgValOptionLong.h"
14 #include "MICmnLLDBDebugSessionInfo.h"
15 #include "MICmnMIValueConst.h"
16
17 //++
18 //------------------------------------------------------------------------------------
19 // Details: CMICmdBase constructor.
20 // Type:    Method.
21 // Args:    None.
22 // Return:  None.
23 // Throws:  None.
24 //--
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) {}
32
33 //++
34 //------------------------------------------------------------------------------------
35 // Details: CMICmdBase destructor.
36 // Type:    Overrideable.
37 // Args:    None.
38 // Return:  None.
39 // Throws:  None.
40 //--
41 CMICmdBase::~CMICmdBase() {}
42
43 //++
44 //------------------------------------------------------------------------------------
45 // Details: The invoker requires this function.
46 // Type:    Overridden.
47 // Args:    None.
48 // Return:  SMICmdData & -  *this command's present status/data/information.
49 // Throws:  None.
50 //--
51 const SMICmdData &CMICmdBase::GetCmdData() const { return m_cmdData; }
52
53 //++
54 //------------------------------------------------------------------------------------
55 // Details: The invoker requires this function.
56 // Type:    Overridden.
57 // Args:    None.
58 // Return:  CMIUtilString & -   *this command's current error description.
59 //                              Empty string indicates command status ok.
60 // Throws:  None.
61 //--
62 const CMIUtilString &CMICmdBase::GetErrorDescription() const {
63   return m_strCurrentErrDescription;
64 }
65
66 //++
67 //------------------------------------------------------------------------------------
68 // Details: The CMICmdFactory requires this function. Retrieve the command and
69 // argument
70 //          options description string.
71 // Type:    Overridden.
72 // Args:    None.
73 // Return:  CMIUtilString & -   Command description.
74 // Throws:  None.
75 //--
76 const CMIUtilString &CMICmdBase::GetMiCmd() const { return m_strMiCmd; }
77
78 //++
79 //------------------------------------------------------------------------------------
80 // Details: Help parse the arguments that are common to all commands.
81 // Args:    None.
82 // Return:  None
83 // Throws:  None.
84 //--
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));
92   m_setCmdArgs.Add(
93       new CMICmdArgValOptionLong(m_constStrArgFrame, m_FrameArgMandatory, true,
94                                  CMICmdArgValListBase::eArgValType_Number, 1));
95   m_setCmdArgs.Add(new CMICmdArgValConsume(m_constStrArgConsume, false));
96 }
97
98 //++
99 //------------------------------------------------------------------------------------
100 // Details: The invoker requires this function. A command must be given working
101 // data and
102 //          provide data about its status or provide information to other
103 //          objects.
104 // Type:    Overridden.
105 // Args:    None.
106 // Return:  None.
107 // Throws:  None.
108 //--
109 void CMICmdBase::SetCmdData(const SMICmdData &vCmdData) {
110   m_cmdData = vCmdData;
111 }
112
113 //++
114 //------------------------------------------------------------------------------------
115 // Details: The command factory requires this function. The factory calls this
116 // function
117 //          so it can obtain *this command's creation function.
118 // Type:    Overridden.
119 // Args:    None.
120 // Return:  CMICmdFactory::CmdCreatorFnPtr - Function pointer.
121 // Throws:  None.
122 //--
123 CMICmdFactory::CmdCreatorFnPtr CMICmdBase::GetCmdCreatorFn() const {
124   return m_pSelfCreatorFn;
125 }
126
127 //++
128 //------------------------------------------------------------------------------------
129 // Details: If a command is an event type (has callbacks registered with
130 // SBListener) it
131 //          needs to inform the Invoker that it has finished its work so that
132 //          the
133 //          Invoker can tidy up and call the commands Acknowledge function (yes
134 //          the
135 //          command itself could call the Acknowledge itself but not doing that
136 //          way).
137 // Type:    Overridden.
138 // Args:    None.
139 // Return:  None.
140 // Throws:  None.
141 //--
142 void CMICmdBase::CmdFinishedTellInvoker() const {
143   CMICmdInvoker::Instance().CmdExecuteFinished(const_cast<CMICmdBase &>(*this));
144 }
145
146 //++
147 //------------------------------------------------------------------------------------
148 // Details: Returns the final version of the MI result record built up in the
149 // command's
150 //          Acknowledge function. The one line text of MI result.
151 // Type:    Overridden.
152 // Args:    None.
153 // Return:  CMIUtilString & - MI text version of the MI result record.
154 // Throws:  None.
155 //--
156 const CMIUtilString &CMICmdBase::GetMIResultRecord() const {
157   return m_miResultRecord.GetString();
158 }
159
160 //++
161 //------------------------------------------------------------------------------------
162 // Details: Retrieve from the command additional MI result to its 1 line
163 // response.
164 //          Because of using LLDB additional 'fake'/hack output is sometimes
165 //          required to
166 //          help the driver client operate i.e. Eclipse.
167 // Type:    Overridden.
168 // Args:    None.
169 // Return:  CMIUtilString & - MI text version of the MI result record.
170 // Throws:  None.
171 //--
172 const CMIUtilString &CMICmdBase::GetMIResultRecordExtra() const {
173   return m_miResultRecordExtra;
174 }
175
176 //++
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
180 //          required to
181 //          help the driver client operate i.e. Eclipse.
182 // Type:    Overridden.
183 // Args:    None.
184 // Return:  bool    - True = Yes have additional MI output, false = no nothing
185 // extra.
186 // Throws:  None.
187 //--
188 bool CMICmdBase::HasMIResultRecordExtra() const {
189   return m_bHasResultRecordExtra;
190 }
191
192 //++
193 //------------------------------------------------------------------------------------
194 // Details: Short cut function to enter error information into the command's
195 // metadata
196 //          object and set the command's error status.
197 // Type:    Method.
198 // Args:    rErrMsg - (R) Status description.
199 // Return:  None.
200 // Throws:  None.
201 //--
202 void CMICmdBase::SetError(const CMIUtilString &rErrMsg) {
203   m_cmdData.bCmdValid = false;
204   m_cmdData.strErrorDescription = rErrMsg;
205   m_cmdData.bCmdExecutedSuccessfully = false;
206
207   const CMICmnMIValueResult valueResult("msg", CMICmnMIValueConst(rErrMsg));
208   const CMICmnMIResultRecord miResultRecord(
209       m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error,
210       valueResult);
211   m_miResultRecord = miResultRecord;
212   m_cmdData.strMiCmdResultRecord = miResultRecord.GetString();
213 }
214
215 //++
216 //------------------------------------------------------------------------------------
217 // Details: Short cut function to check MI command's execute status and
218 //          set an error in case of failure.
219 // Type:    Method.
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.
225 // Return:  bool.
226 // Throws:  None.
227 //--
228 bool CMICmdBase::HandleSBError(const lldb::SBError &error,
229                                const std::function<bool()> &successHandler,
230                                const std::function<void()> &errorHandler) {
231   if (error.Success())
232     return successHandler();
233
234   SetError(error.GetCString());
235   errorHandler();
236   return MIstatus::failure;
237 }
238
239 //++
240 //------------------------------------------------------------------------------------
241 // Details: Short cut function to check MI command's execute status and
242 //          call specified handler function for success case.
243 // Type:    Method.
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.
247 // Return:  bool.
248 // Throws:  None.
249 //--
250 bool CMICmdBase::HandleSBErrorWithSuccess(
251     const lldb::SBError &error,
252     const std::function<bool()> &successHandler) {
253   return HandleSBError(error, successHandler);
254 }
255
256 //++
257 //------------------------------------------------------------------------------------
258 // Details: Short cut function to check MI command's execute status and
259 //          call specified handler function for error case.
260 // Type:    Method.
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.
264 // Return:  bool.
265 // Throws:  None.
266 //--
267 bool CMICmdBase::HandleSBErrorWithFailure(
268     const lldb::SBError &error,
269     const std::function<void()> &errorHandler) {
270   return HandleSBError(error, [] { return MIstatus::success; }, errorHandler);
271 }
272
273 //++
274 //------------------------------------------------------------------------------------
275 // Details: Ask a command to provide its unique identifier.
276 // Type:    Method.
277 // Args:    A unique identifier for this command class.
278 // Return:  None.
279 // Throws:  None.
280 //--
281 MIuint CMICmdBase::GetGUID() {
282   MIuint64 vptr = reinterpret_cast<MIuint64>(this);
283   MIuint id = (vptr)&0xFFFFFFFF;
284   id ^= (vptr >> 32) & 0xFFFFFFFF;
285
286   return id;
287 }
288
289 //++
290 //------------------------------------------------------------------------------------
291 // Details: The invoker requires this function. The parses the command line
292 // options
293 //          arguments to extract values for each of those arguments.
294 // Type:    Overridden.
295 // Args:    None.
296 // Return:  MIstatus::success - Functional succeeded.
297 //          MIstatus::failure - Functional failed.
298 // Throws:  None.
299 //--
300 bool CMICmdBase::ParseArgs() {
301   // Do nothing - override to implement
302
303   return MIstatus::success;
304 }
305
306 //++
307 //------------------------------------------------------------------------------------
308 // Details: Having previously given CMICmdArgSet m_setCmdArgs all the argument
309 // or option
310 //          definitions for the command to handle proceed to parse and validate
311 //          the
312 //          command's options text for those arguments and extract the values
313 //          for each if
314 //          any.
315 // Type:    Method.
316 // Args:    None.
317 // Return:  MIstatus::success - Functional succeeded.
318 //          MIstatus::failure - Functional failed.
319 // Throws:  None.
320 //--
321 bool CMICmdBase::ParseValidateCmdOptions() {
322   CMICmdArgContext argCntxt(m_cmdData.strMiCmdOption);
323   if (m_setCmdArgs.Validate(m_cmdData.strMiCmd, argCntxt))
324     return MIstatus::success;
325
326   SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_ARGS),
327                                  m_cmdData.strMiCmd.c_str(),
328                                  m_setCmdArgs.GetErrorDescription().c_str()));
329
330   return MIstatus::failure;
331 }
332
333 //++
334 //------------------------------------------------------------------------------------
335 // Details: If the MI Driver is not operating via a client i.e. Eclipse but say
336 // operating
337 //          on a executable passed in as a argument to the drive then what
338 //          should the driver
339 //          do on a command failing? Either continue operating or exit the
340 //          application.
341 //          Override this function where a command failure cannot allow the
342 //          driver to
343 //          continue operating.
344 // Type:    Overrideable.
345 // Args:    None.
346 // Return:  bool - True = Fatal if command fails, false = can continue if
347 // command fails.
348 // Throws:  None.
349 //--
350 bool CMICmdBase::GetExitAppOnCommandFailure() const { return false; }