]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/tools/lldb-mi/MICmdFactory.cpp
Merge libc++ trunk r366426, resolve conflicts, and add FREEBSD-Xlist.
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / tools / lldb-mi / MICmdFactory.cpp
1 //===-- MICmdFactory.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 "MICmdFactory.h"
11 #include "MICmdBase.h"
12 #include "MICmdCommands.h"
13 #include "MICmdData.h"
14 #include "MICmnResources.h"
15
16 //++
17 // Details: CMICmdFactory constructor.
18 // Type:    Method.
19 // Args:    None.
20 // Return:  None.
21 // Throws:  None.
22 //--
23 CMICmdFactory::CMICmdFactory() {}
24
25 //++
26 // Details: CMICmdFactory destructor.
27 // Type:    Overridable.
28 // Args:    None.
29 // Return:  None.
30 // Throws:  None.
31 //--
32 CMICmdFactory::~CMICmdFactory() { Shutdown(); }
33
34 //++
35 // Details: Initialize resources for *this Command factory.
36 // Type:    Method.
37 // Args:    None.
38 // Return:  MIstatus::success - Functionality succeeded.
39 //          MIstatus::failure - Functionality failed.
40 // Throws:  None.
41 //--
42 bool CMICmdFactory::Initialize() {
43   m_clientUsageRefCnt++;
44
45   if (m_bInitialized)
46     return MIstatus::success;
47
48   m_bInitialized = true;
49
50   MICmnCommands::RegisterAll();
51
52   return MIstatus::success;
53 }
54
55 //++
56 // Details: Release resources for *this Command Factory.
57 // Type:    Method.
58 // Args:    None.
59 // Return:  MIstatus::success - Functionality succeeded.
60 //          MIstatus::failure - Functionality failed.
61 // Throws:  None.
62 //--
63 bool CMICmdFactory::Shutdown() {
64   if (--m_clientUsageRefCnt > 0)
65     return MIstatus::success;
66
67   if (!m_bInitialized)
68     return MIstatus::success;
69
70   m_mapMiCmdToCmdCreatorFn.clear();
71
72   m_bInitialized = false;
73
74   return MIstatus::success;
75 }
76
77 //++
78 // Details: Register a command's creator function with the command identifier
79 // the MI
80 //          command name i.e. 'file-exec-and-symbols'.
81 // Type:    Method.
82 // Args:    vMiCmd          - (R) Command's name, the MI command.
83 //          vCmdCreateFn    - (R) Command's creator function pointer.
84 // Return:  MIstatus::success - Functionality succeeded.
85 //          MIstatus::failure - Functionality failed.
86 // Throws:  None.
87 //--
88 bool CMICmdFactory::CmdRegister(const CMIUtilString &vMiCmd,
89                                 CmdCreatorFnPtr vCmdCreateFn) {
90   if (!IsValid(vMiCmd)) {
91     SetErrorDescription(CMIUtilString::Format(
92         MIRSRC(IDS_CMDFACTORY_ERR_INVALID_CMD_NAME), vMiCmd.c_str()));
93     return MIstatus::failure;
94   }
95   if (vCmdCreateFn == nullptr) {
96     SetErrorDescription(CMIUtilString::Format(
97         MIRSRC(IDS_CMDFACTORY_ERR_INVALID_CMD_CR8FN), vMiCmd.c_str()));
98     return MIstatus::failure;
99   }
100
101   if (HaveAlready(vMiCmd)) {
102     SetErrorDescription(CMIUtilString::Format(
103         MIRSRC(IDS_CMDFACTORY_ERR_CMD_ALREADY_REGED), vMiCmd.c_str()));
104     return MIstatus::failure;
105   }
106
107   MapPairMiCmdToCmdCreatorFn_t pr(vMiCmd, vCmdCreateFn);
108   m_mapMiCmdToCmdCreatorFn.insert(pr);
109
110   return MIstatus::success;
111 }
112
113 //++
114 // Details: Check a command is already registered.
115 // Type:    Method.
116 // Args:    vMiCmd  - (R) Command's name, the MI command.
117 // Return:  True - registered.
118 //          False - not found.
119 // Throws:  None.
120 //--
121 bool CMICmdFactory::HaveAlready(const CMIUtilString &vMiCmd) const {
122   const MapMiCmdToCmdCreatorFn_t::const_iterator it =
123       m_mapMiCmdToCmdCreatorFn.find(vMiCmd);
124   return it != m_mapMiCmdToCmdCreatorFn.end();
125 }
126
127 //++
128 // Details: Check a command's name is valid:
129 //              - name is not empty
130 //              - name does not have spaces
131 // Type:    Method.
132 // Args:    vMiCmd  - (R) Command's name, the MI command.
133 // Return:  True - valid.
134 //          False - not valid.
135 // Throws:  None.
136 //--
137 bool CMICmdFactory::IsValid(const CMIUtilString &vMiCmd) const {
138   bool bValid = true;
139
140   if (vMiCmd.empty()) {
141     bValid = false;
142     return false;
143   }
144
145   const size_t nPos = vMiCmd.find(' ');
146   if (nPos != std::string::npos)
147     bValid = false;
148
149   return bValid;
150 }
151
152 //++
153 // Details: Check a command is already registered.
154 // Type:    Method.
155 // Args:    vMiCmd  - (R) Command's name, the MI command.
156 // Return:  True - registered.
157 //          False - not found.
158 // Throws:  None.
159 //--
160 bool CMICmdFactory::CmdExist(const CMIUtilString &vMiCmd) const {
161   return HaveAlready(vMiCmd);
162 }
163
164 //++
165 // Details: Create a command given the specified MI command name. The command
166 // data object
167 //          contains the options for the command.
168 // Type:    Method.
169 // Args:    vMiCmd      - (R) Command's name, the MI command.
170 //          vCmdData    - (RW) Command's metadata status/information/result
171 //          object.
172 //          vpNewCmd    - (W) New command instance.
173 // Return:  MIstatus::success - Functionality succeeded.
174 //          MIstatus::failure - Functionality failed.
175 // Throws:  None.
176 //--
177 bool CMICmdFactory::CmdCreate(const CMIUtilString &vMiCmd,
178                               const SMICmdData &vCmdData,
179                               CMICmdBase *&vpNewCmd) {
180   vpNewCmd = nullptr;
181
182   if (!IsValid(vMiCmd)) {
183     SetErrorDescription(CMIUtilString::Format(
184         MIRSRC(IDS_CMDFACTORY_ERR_INVALID_CMD_NAME), vMiCmd.c_str()));
185     return MIstatus::failure;
186   }
187   if (!HaveAlready(vMiCmd)) {
188     SetErrorDescription(CMIUtilString::Format(
189         MIRSRC(IDS_CMDFACTORY_ERR_CMD_NOT_REGISTERED), vMiCmd.c_str()));
190     return MIstatus::failure;
191   }
192
193   const MapMiCmdToCmdCreatorFn_t::const_iterator it =
194       m_mapMiCmdToCmdCreatorFn.find(vMiCmd);
195   const CMIUtilString &rMiCmd((*it).first);
196   MIunused(rMiCmd);
197   CmdCreatorFnPtr pFn = (*it).second;
198   CMICmdBase *pCmd = (*pFn)();
199
200   SMICmdData cmdData(vCmdData);
201   cmdData.id = pCmd->GetGUID();
202   pCmd->SetCmdData(cmdData);
203   vpNewCmd = pCmd;
204
205   return MIstatus::success;
206 }