]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/tools/lldb-mi/MICmdMgr.cpp
Merge ^/head r338298 through r338391.
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / tools / lldb-mi / MICmdMgr.cpp
1 //===-- MICmdMgr.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 "MICmdMgr.h"
12 #include "MICmdBase.h"
13 #include "MICmdFactory.h"
14 #include "MICmdInterpreter.h"
15 #include "MICmdInvoker.h"
16 #include "MICmnLog.h"
17 #include "MICmnResources.h"
18 #include "MIUtilSingletonBase.h"
19 #include "MIUtilSingletonHelper.h"
20
21 //++
22 //------------------------------------------------------------------------------------
23 // Details: CMICmdMgr constructor.
24 // Type:    Method.
25 // Args:    None.
26 // Return:  None.
27 // Throws:  None.
28 //--
29 CMICmdMgr::CMICmdMgr()
30     : m_interpretor(CMICmdInterpreter::Instance()),
31       m_factory(CMICmdFactory::Instance()),
32       m_invoker(CMICmdInvoker::Instance()) {}
33
34 //++
35 //------------------------------------------------------------------------------------
36 // Details: CMICmdMgr destructor.
37 // Type:    Overridable.
38 // Args:    None.
39 // Return:  None.
40 // Throws:  None.
41 //--
42 CMICmdMgr::~CMICmdMgr() { Shutdown(); }
43
44 //++
45 //------------------------------------------------------------------------------------
46 // Details: Initialize resources for *this Command Manager.
47 // Type:    Method.
48 // Args:    None.
49 // Return:  MIstatus::success - Functionality succeeded.
50 //          MIstatus::failure - Functionality failed.
51 // Throws:  None.
52 //--
53 bool CMICmdMgr::Initialize() {
54   m_clientUsageRefCnt++;
55
56   if (m_bInitialized)
57     return MIstatus::success;
58
59   bool bOk = MIstatus::success;
60   CMIUtilString errMsg;
61
62   // Note initialization order is important here as some resources depend on
63   // previous
64   MI::ModuleInit<CMICmnLog>(IDS_MI_INIT_ERR_LOG, bOk, errMsg);
65   MI::ModuleInit<CMICmnResources>(IDS_MI_INIT_ERR_RESOURCES, bOk, errMsg);
66   if (bOk && !m_interpretor.Initialize()) {
67     bOk = false;
68     errMsg = CMIUtilString::Format(MIRSRC(IDS_MI_INIT_ERR_CMDINTERPRETER),
69                                    m_interpretor.GetErrorDescription().c_str());
70   }
71   if (bOk && !m_factory.Initialize()) {
72     bOk = false;
73     errMsg = CMIUtilString::Format(MIRSRC(IDS_MI_INIT_ERR_CMDFACTORY),
74                                    m_factory.GetErrorDescription().c_str());
75   }
76   if (bOk && !m_invoker.Initialize()) {
77     bOk = false;
78     errMsg = CMIUtilString::Format(MIRSRC(IDS_MI_INIT_ERR_CMDINVOKER),
79                                    m_invoker.GetErrorDescription().c_str());
80   }
81   m_bInitialized = bOk;
82
83   if (!bOk) {
84     CMIUtilString strInitError(
85         CMIUtilString::Format(MIRSRC(IDS_MI_INIT_ERR_CMDMGR), errMsg.c_str()));
86     SetErrorDescription(strInitError);
87     return MIstatus::failure;
88   }
89
90   return MIstatus::success;
91 }
92
93 //++
94 //------------------------------------------------------------------------------------
95 // Details: Release resources for *this Command Manager.
96 // Type:    Method.
97 // Args:    None.
98 // Return:  MIstatus::success - Functionality succeeded.
99 //          MIstatus::failure - Functionality failed.
100 // Throws:  None.
101 //--
102 bool CMICmdMgr::Shutdown() {
103   if (--m_clientUsageRefCnt > 0)
104     return MIstatus::success;
105
106   if (!m_bInitialized)
107     return MIstatus::success;
108
109   m_bInitialized = false;
110
111   ClrErrorDescription();
112
113   bool bOk = MIstatus::success;
114   CMIUtilString errMsg;
115
116   // Tidy up
117   m_setCmdDeleteCallback.clear();
118
119   // Note shutdown order is important here
120   if (!m_invoker.Shutdown()) {
121     bOk = false;
122     errMsg += CMIUtilString::Format(MIRSRC(IDS_MI_SHTDWN_ERR_CMDINVOKER),
123                                     m_invoker.GetErrorDescription().c_str());
124   }
125   if (!m_factory.Shutdown()) {
126     bOk = false;
127     if (!errMsg.empty())
128       errMsg += ", ";
129     errMsg += CMIUtilString::Format(MIRSRC(IDS_MI_SHTDWN_ERR_CMDFACTORY),
130                                     m_factory.GetErrorDescription().c_str());
131   }
132   if (!m_interpretor.Shutdown()) {
133     bOk = false;
134     if (!errMsg.empty())
135       errMsg += ", ";
136     errMsg +=
137         CMIUtilString::Format(MIRSRC(IDS_MI_SHTDWN_ERR_CMDINTERPRETER),
138                               m_interpretor.GetErrorDescription().c_str());
139   }
140   MI::ModuleShutdown<CMICmnResources>(IDS_MI_INIT_ERR_RESOURCES, bOk, errMsg);
141   MI::ModuleShutdown<CMICmnLog>(IDS_MI_INIT_ERR_LOG, bOk, errMsg);
142
143   if (!bOk) {
144     SetErrorDescriptionn(MIRSRC(IDS_MI_SHUTDOWN_ERR), errMsg.c_str());
145   }
146
147   return MIstatus::success;
148 }
149
150 //++
151 //------------------------------------------------------------------------------------
152 // Details: Establish whether the text data is an MI format type command.
153 // Type:    Method.
154 // Args:    vTextLine               - (R) Text data to interpret.
155 //          vwbYesValid             - (W) True = MI type command, false = not
156 //          recognised.
157 //          vwbCmdNotInCmdFactor    - (W) True = MI command not found in the
158 //          command factor, false = recognised.
159 // Return:  MIstatus::success - Functionality succeeded.
160 //          MIstatus::failure - Functionality failed.
161 // Throws:  None.
162 //--
163 bool CMICmdMgr::CmdInterpret(const CMIUtilString &vTextLine, bool &vwbYesValid,
164                              bool &vwbCmdNotInCmdFactor,
165                              SMICmdData &rwCmdData) {
166   return m_interpretor.ValidateIsMi(vTextLine, vwbYesValid,
167                                     vwbCmdNotInCmdFactor, rwCmdData);
168 }
169
170 //++
171 //------------------------------------------------------------------------------------
172 // Details: Having previously had the potential command validated and found
173 // valid now
174 //          get the command executed.
175 //          If the Functionality returns MIstatus::failure call
176 //          GetErrorDescription().
177 //          This function is used by the application's main thread.
178 // Type:    Method.
179 // Args:    vCmdData    - (RW) Command meta data.
180 // Return:  MIstatus::success - Functionality succeeded.
181 //          MIstatus::failure - Functionality failed.
182 // Throws:  None.
183 //--
184 bool CMICmdMgr::CmdExecute(const SMICmdData &vCmdData) {
185   bool bOk = MIstatus::success;
186
187   // Pass the command's meta data structure to the command
188   // so it can update it if required. (Need to copy it out of the
189   // command before the command is deleted)
190   CMICmdBase *pCmd = nullptr;
191   bOk = m_factory.CmdCreate(vCmdData.strMiCmd, vCmdData, pCmd);
192   if (!bOk) {
193     const CMIUtilString errMsg(
194         CMIUtilString::Format(MIRSRC(IDS_CMDMGR_ERR_CMD_FAILED_CREATE),
195                               m_factory.GetErrorDescription().c_str()));
196     SetErrorDescription(errMsg);
197     return MIstatus::failure;
198   }
199
200   bOk = m_invoker.CmdExecute(*pCmd);
201   if (!bOk) {
202     const CMIUtilString errMsg(
203         CMIUtilString::Format(MIRSRC(IDS_CMDMGR_ERR_CMD_INVOKER),
204                               m_invoker.GetErrorDescription().c_str()));
205     SetErrorDescription(errMsg);
206     return MIstatus::failure;
207   }
208
209   return bOk;
210 }
211
212 //++
213 //------------------------------------------------------------------------------------
214 // Details: Iterate all interested clients and tell them a command is being
215 // deleted.
216 // Type:    Method.
217 // Args:    vCmdData    - (RW) The command to be deleted.
218 // Return:  MIstatus::success - Functional succeeded.
219 //          MIstatus::failure - Functional failed.
220 // Throws:  None.
221 //--
222 bool CMICmdMgr::CmdDelete(SMICmdData vCmdData) {
223   // Note vCmdData is a copy! The command holding its copy will be deleted soon
224   // we still need to iterate callback clients after a command object is deleted
225
226   m_setCmdDeleteCallback.Delete(vCmdData);
227
228   return MIstatus::success;
229 }
230
231 //++
232 //------------------------------------------------------------------------------------
233 // Details: Register an object to be called when a command object is deleted.
234 // Type:    Method.
235 // Args:    vObject - (R) A new interested client.
236 // Return:  MIstatus::success - Functional succeeded.
237 //          MIstatus::failure - Functional failed.
238 // Throws:  None.
239 //--
240 bool CMICmdMgr::CmdRegisterForDeleteNotification(
241     CMICmdMgrSetCmdDeleteCallback::ICallback &vObject) {
242   return m_setCmdDeleteCallback.Register(vObject);
243 }
244
245 //++
246 //------------------------------------------------------------------------------------
247 // Details: Unregister an object from being called when a command object is
248 // deleted.
249 // Type:    Method.
250 // Args:    vObject - (R) The was interested client.
251 // Return:  MIstatus::success - Functional succeeded.
252 //          MIstatus::failure - Functional failed.
253 // Throws:  None.
254 //--
255 bool CMICmdMgr::CmdUnregisterForDeleteNotification(
256     CMICmdMgrSetCmdDeleteCallback::ICallback &vObject) {
257   return m_setCmdDeleteCallback.Unregister(vObject);
258 }