File: | tools/lldb/tools/lldb-mi/MICmdInvoker.cpp |
Warning: | line 308, column 5 Value stored to 'bOk' is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | //===-- MICmdInvoker.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 "MICmdInvoker.h" |
12 | #include "MICmdBase.h" |
13 | #include "MICmdMgr.h" |
14 | #include "MICmnLog.h" |
15 | #include "MICmnStreamStdout.h" |
16 | #include "MIDriver.h" |
17 | |
18 | //++ |
19 | //------------------------------------------------------------------------------------ |
20 | // Details: CMICmdInvoker constructor. |
21 | // Type: Method. |
22 | // Args: None. |
23 | // Return: None. |
24 | // Throws: None. |
25 | //-- |
26 | CMICmdInvoker::CMICmdInvoker() : m_rStreamOut(CMICmnStreamStdout::Instance()) {} |
27 | |
28 | //++ |
29 | //------------------------------------------------------------------------------------ |
30 | // Details: CMICmdInvoker destructor. |
31 | // Type: Overridable. |
32 | // Args: None. |
33 | // Return: None. |
34 | // Throws: None. |
35 | //-- |
36 | CMICmdInvoker::~CMICmdInvoker() { Shutdown(); } |
37 | |
38 | //++ |
39 | //------------------------------------------------------------------------------------ |
40 | // Details: Initialize resources for *this Command Invoker. |
41 | // Type: Method. |
42 | // Args: None. |
43 | // Return: MIstatus::success - Functional succeeded. |
44 | // MIstatus::failure - Functional failed. |
45 | // Throws: None. |
46 | //-- |
47 | bool CMICmdInvoker::Initialize() { |
48 | m_clientUsageRefCnt++; |
49 | |
50 | if (m_bInitialized) |
51 | return MIstatus::success; |
52 | |
53 | m_bInitialized = true; |
54 | |
55 | return MIstatus::success; |
56 | } |
57 | |
58 | //++ |
59 | //------------------------------------------------------------------------------------ |
60 | // Details: Release resources for *this Stdin stream. |
61 | // Type: Method. |
62 | // Args: None. |
63 | // Return: MIstatus::success - Functional succeeded. |
64 | // MIstatus::failure - Functional failed. |
65 | // Throws: None. |
66 | //-- |
67 | bool CMICmdInvoker::Shutdown() { |
68 | if (--m_clientUsageRefCnt > 0) |
69 | return MIstatus::success; |
70 | |
71 | if (!m_bInitialized) |
72 | return MIstatus::success; |
73 | |
74 | CmdDeleteAll(); |
75 | |
76 | m_bInitialized = false; |
77 | |
78 | return MIstatus::success; |
79 | } |
80 | |
81 | //++ |
82 | //------------------------------------------------------------------------------------ |
83 | // Details: Empty the map of invoked commands doing work. Command objects are |
84 | // deleted too. |
85 | // Type: Method. |
86 | // Args: None. |
87 | // Return: None. |
88 | // Throws: None. |
89 | //-- |
90 | void CMICmdInvoker::CmdDeleteAll() { |
91 | CMICmdMgr &rMgr = CMICmdMgr::Instance(); |
92 | MapCmdIdToCmd_t::const_iterator it = m_mapCmdIdToCmd.begin(); |
93 | while (it != m_mapCmdIdToCmd.end()) { |
94 | const MIuint cmdId((*it).first); |
95 | MIunused(cmdId)(void)cmdId;; |
96 | CMICmdBase *pCmd = (*it).second; |
97 | const CMIUtilString &rCmdName(pCmd->GetCmdData().strMiCmd); |
98 | MIunused(rCmdName)(void)rCmdName;; |
99 | rMgr.CmdDelete(pCmd->GetCmdData()); |
100 | |
101 | // Next |
102 | ++it; |
103 | } |
104 | m_mapCmdIdToCmd.clear(); |
105 | } |
106 | |
107 | //++ |
108 | //------------------------------------------------------------------------------------ |
109 | // Details: Remove from the map of invoked commands doing work a command that |
110 | // has finished |
111 | // its work. The command object is deleted too. |
112 | // Type: Method. |
113 | // Args: vId - (R) Command object's unique ID. |
114 | // vbYesDeleteCmd - (R) True = Delete command object, false = delete |
115 | // via the Command Manager. |
116 | // Return: None. |
117 | // Throws: None. |
118 | //-- |
119 | bool CMICmdInvoker::CmdDelete(const MIuint vId, |
120 | const bool vbYesDeleteCmd /*= false*/) { |
121 | CMICmdMgr &rMgr = CMICmdMgr::Instance(); |
122 | MapCmdIdToCmd_t::const_iterator it = m_mapCmdIdToCmd.find(vId); |
123 | if (it != m_mapCmdIdToCmd.end()) { |
124 | CMICmdBase *pCmd = (*it).second; |
125 | if (vbYesDeleteCmd) { |
126 | // Via registered interest command manager callback *this object to delete |
127 | // the command |
128 | m_mapCmdIdToCmd.erase(it); |
129 | delete pCmd; |
130 | } else |
131 | // Notify other interested object of this command's pending deletion |
132 | rMgr.CmdDelete(pCmd->GetCmdData()); |
133 | } |
134 | |
135 | if (m_mapCmdIdToCmd.empty()) |
136 | rMgr.CmdUnregisterForDeleteNotification(*this); |
137 | |
138 | return MIstatus::success; |
139 | } |
140 | |
141 | //++ |
142 | //------------------------------------------------------------------------------------ |
143 | // Details: Add to the map of invoked commands doing work a command that is |
144 | // about to |
145 | // start to do work. |
146 | // Type: Method. |
147 | // Args: vCmd - (R) Command object. |
148 | // Return: None. |
149 | // Throws: None. |
150 | //-- |
151 | bool CMICmdInvoker::CmdAdd(const CMICmdBase &vCmd) { |
152 | if (m_mapCmdIdToCmd.empty()) { |
153 | CMICmdMgr &rMgr = CMICmdMgr::Instance(); |
154 | rMgr.CmdRegisterForDeleteNotification(*this); |
155 | } |
156 | |
157 | const MIuint &cmdId(vCmd.GetCmdData().id); |
158 | MapCmdIdToCmd_t::const_iterator it = m_mapCmdIdToCmd.find(cmdId); |
159 | if (it != m_mapCmdIdToCmd.end()) |
160 | return MIstatus::success; |
161 | |
162 | MapPairCmdIdToCmd_t pr(cmdId, const_cast<CMICmdBase *>(&vCmd)); |
163 | m_mapCmdIdToCmd.insert(pr); |
164 | |
165 | return MIstatus::success; |
166 | } |
167 | |
168 | //++ |
169 | //------------------------------------------------------------------------------------ |
170 | // Details: Having previously had the potential command validated and found |
171 | // valid now |
172 | // get the command executed. |
173 | // If the Functionality returns MIstatus::failure call |
174 | // GetErrorDescription(). |
175 | // This function is used by the application's main thread. |
176 | // Type: Method. |
177 | // Args: vCmd - (RW) Command object. |
178 | // Return: MIstatus::success - Functionality succeeded. |
179 | // MIstatus::failure - Functionality failed. |
180 | // Throws: None. |
181 | //-- |
182 | bool CMICmdInvoker::CmdExecute(CMICmdBase &vCmd) { |
183 | bool bOk = CmdAdd(vCmd); |
184 | |
185 | if (bOk) { |
186 | vCmd.AddCommonArgs(); |
187 | if (!vCmd.ParseArgs()) { |
188 | // Report command execution failed |
189 | const SMICmdData cmdData(vCmd.GetCmdData()); |
190 | CmdStdout(cmdData); |
191 | CmdCauseAppExit(vCmd); |
192 | CmdDelete(cmdData.id); |
193 | |
194 | // Proceed to wait or execute next command |
195 | return MIstatus::success; |
196 | } |
197 | } |
198 | |
199 | if (bOk && !vCmd.Execute()) { |
200 | // Report command execution failed |
201 | const SMICmdData cmdData(vCmd.GetCmdData()); |
202 | CmdStdout(cmdData); |
203 | CmdCauseAppExit(vCmd); |
204 | CmdDelete(cmdData.id); |
205 | |
206 | // Proceed to wait or execute next command |
207 | return MIstatus::success; |
208 | } |
209 | |
210 | bOk = CmdExecuteFinished(vCmd); |
211 | |
212 | return bOk; |
213 | } |
214 | |
215 | //++ |
216 | //------------------------------------------------------------------------------------ |
217 | // Details: Called when a command has finished its Execution() work either |
218 | // synchronously |
219 | // because the command executed was the type a non event type or |
220 | // asynchronously |
221 | // via the command's callback (because of an SB Listener event). Needs |
222 | // to be called |
223 | // so that *this invoker call do some house keeping and then proceed to |
224 | // call |
225 | // the command's Acknowledge() function. |
226 | // Type: Method. |
227 | // Args: vCmd - (R) Command object. |
228 | // Return: MIstatus::success - Functionality succeeded. |
229 | // MIstatus::failure - Functionality failed. |
230 | // Throws: None. |
231 | //-- |
232 | bool CMICmdInvoker::CmdExecuteFinished(CMICmdBase &vCmd) { |
233 | // Command finished now get the command to gather it's information and form |
234 | // the MI |
235 | // Result record |
236 | if (!vCmd.Acknowledge()) { |
237 | // Report command acknowledge functionality failed |
238 | const SMICmdData cmdData(vCmd.GetCmdData()); |
239 | CmdStdout(cmdData); |
240 | CmdCauseAppExit(vCmd); |
241 | CmdDelete(cmdData.id); |
242 | |
243 | // Proceed to wait or execute next command |
244 | return MIstatus::success; |
245 | } |
246 | |
247 | // Retrieve the command's latest data/information. Needed for commands of the |
248 | // event type so have |
249 | // a record of commands pending finishing execution. |
250 | const CMIUtilString &rMIResultRecord(vCmd.GetMIResultRecord()); |
251 | SMICmdData cmdData( |
252 | vCmd.GetCmdData()); // Make a copy as the command will be deleted soon |
253 | cmdData.strMiCmdResultRecord = rMIResultRecord; // Precautionary copy as the |
254 | // command might forget to do |
255 | // this |
256 | if (vCmd.HasMIResultRecordExtra()) { |
257 | cmdData.bHasResultRecordExtra = true; |
258 | const CMIUtilString &rMIExtra(vCmd.GetMIResultRecordExtra()); |
259 | cmdData.strMiCmdResultRecordExtra = |
260 | rMIExtra; // Precautionary copy as the command might forget to do this |
261 | } |
262 | |
263 | // Send command's MI response to the client |
264 | bool bOk = CmdStdout(cmdData); |
265 | |
266 | // Delete the command object as do not require anymore |
267 | bOk = bOk && CmdDelete(vCmd.GetCmdData().id); |
268 | |
269 | return bOk; |
270 | } |
271 | |
272 | //++ |
273 | //------------------------------------------------------------------------------------ |
274 | // Details: If the MI Driver is not operating via a client i.e. Eclipse check |
275 | // the command |
276 | // on failure suggests the application exits. A command can be such |
277 | // that a |
278 | // failure cannot the allow the application to continue operating. |
279 | // Args: vCmd - (R) Command object. |
280 | // Return: None. |
281 | // Return: None. |
282 | // Throws: None. |
283 | //-- |
284 | void CMICmdInvoker::CmdCauseAppExit(const CMICmdBase &vCmd) const { |
285 | if (vCmd.GetExitAppOnCommandFailure()) { |
286 | CMIDriver &rDriver(CMIDriver::Instance()); |
287 | if (rDriver.IsDriverDebuggingArgExecutable()) { |
288 | rDriver.SetExitApplicationFlag(true); |
289 | } |
290 | } |
291 | } |
292 | |
293 | //++ |
294 | //------------------------------------------------------------------------------------ |
295 | // Details: Write to stdout and the Log file the command's MI formatted result. |
296 | // Type: vCmdData - (R) A command's information. |
297 | // Return: MIstatus::success - Functionality succeeded. |
298 | // MIstatus::failure - Functionality failed. |
299 | // Return: None. |
300 | // Throws: None. |
301 | //-- |
302 | bool CMICmdInvoker::CmdStdout(const SMICmdData &vCmdData) const { |
303 | bool bOk = m_pLog->WriteLog(vCmdData.strMiCmdAll); |
304 | const bool bLock = bOk && m_rStreamOut.Lock(); |
305 | bOk = bOk && bLock && |
306 | m_rStreamOut.WriteMIResponse(vCmdData.strMiCmdResultRecord); |
307 | if (bOk && vCmdData.bHasResultRecordExtra) { |
308 | bOk = m_rStreamOut.WriteMIResponse(vCmdData.strMiCmdResultRecordExtra); |
Value stored to 'bOk' is never read | |
309 | } |
310 | bOk = bLock && m_rStreamOut.Unlock(); |
311 | |
312 | return bOk; |
313 | } |
314 | |
315 | //++ |
316 | //------------------------------------------------------------------------------------ |
317 | // Details: Required by the CMICmdMgr::ICmdDeleteCallback. *this object is |
318 | // registered |
319 | // with the Command Manager to receive callbacks when a command is |
320 | // being deleted. |
321 | // An object, *this invoker, does not delete a command object itself |
322 | // but calls |
323 | // the Command Manager to delete a command object. This function is the |
324 | // Invoker's |
325 | // called. |
326 | // The Invoker owns the command objects and so can delete them but must |
327 | // do it |
328 | // via the manager so other objects can be notified of the deletion. |
329 | // Type: Method. |
330 | // Args: vCmd - (RW) Command. |
331 | // Return: None. |
332 | // Throws: None. |
333 | //-- |
334 | void CMICmdInvoker::Delete(SMICmdData &vCmd) { CmdDelete(vCmd.id, true); } |