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