]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/tools/lldb-mi/MICmdInterpreter.cpp
Update OpenSSL to 1.1.1.
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / tools / lldb-mi / MICmdInterpreter.cpp
1 //===-- MICmdInterpreter.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 "MICmdInterpreter.h"
12 #include "MICmdFactory.h"
13
14 //++
15 //------------------------------------------------------------------------------------
16 // Details: CMICmdInterpreter constructor.
17 // Type:    Method.
18 // Args:    None.
19 // Return:  None.
20 // Throws:  None.
21 //--
22 CMICmdInterpreter::CMICmdInterpreter()
23     : m_rCmdFactory(CMICmdFactory::Instance()) {}
24
25 //++
26 //------------------------------------------------------------------------------------
27 // Details: CMICmdInterpreter destructor.
28 // Type:    Overridable.
29 // Args:    None.
30 // Return:  None.
31 // Throws:  None.
32 //--
33 CMICmdInterpreter::~CMICmdInterpreter() { Shutdown(); }
34
35 //++
36 //------------------------------------------------------------------------------------
37 // Details: Initialize resources for *this Command Interpreter.
38 // Type:    Method.
39 // Args:    None.
40 // Return:  MIstatus::success - Functional succeeded.
41 //          MIstatus::failure - Functional failed.
42 // Throws:  None.
43 //--
44 bool CMICmdInterpreter::Initialize() {
45   m_clientUsageRefCnt++;
46
47   if (m_bInitialized)
48     return MIstatus::success;
49
50   m_bInitialized = true;
51
52   return MIstatus::success;
53 }
54
55 //++
56 //------------------------------------------------------------------------------------
57 // Details: Release resources for *this Command Interpreter.
58 // Type:    Method.
59 // Args:    None.
60 // Return:  MIstatus::success - Functional succeeded.
61 //          MIstatus::failure - Functional failed.
62 // Throws:  None.
63 //--
64 bool CMICmdInterpreter::Shutdown() {
65   if (--m_clientUsageRefCnt > 0)
66     return MIstatus::success;
67
68   if (!m_bInitialized)
69     return MIstatus::success;
70
71   m_bInitialized = false;
72
73   return MIstatus::success;
74 }
75
76 //++
77 //------------------------------------------------------------------------------------
78 // Details: Establish whether the text data is an MI format type command.
79 // Type:    Method.
80 // Args:    vTextLine               - (R) Text data to interpret.
81 //          vwbYesValid             - (W) True = MI type command, false = not
82 //          recognised.
83 //          vwbCmdNotInCmdFactor    - (W) True = MI command not found in the
84 //          command factory, false = recognised.
85 // Return:  MIstatus::success - Functional succeeded.
86 //          MIstatus::failure - Functional failed.
87 // Throws:  None.
88 //--
89 bool CMICmdInterpreter::ValidateIsMi(const CMIUtilString &vTextLine,
90                                      bool &vwbYesValid,
91                                      bool &vwbCmdNotInCmdFactor,
92                                      SMICmdData &rwCmdData) {
93   vwbYesValid = false;
94   vwbCmdNotInCmdFactor = false;
95   rwCmdData.Clear();
96
97   if (vTextLine.empty())
98     return MIstatus::success;
99
100   // MI format is [cmd #]-[command name]<space>[command arg(s)]
101   // i.e. 1-file-exec-and-symbols --thread-group i1 DEVICE_EXECUTABLE
102   //      5-data-evaluate-expression --thread 1 --frame 0 *(argv)
103
104   m_miCmdData.Clear();
105   m_miCmdData.strMiCmd = vTextLine;
106
107   // The following change m_miCmdData as valid parts are identified
108   vwbYesValid = (MiHasCmdTokenEndingHyphen(vTextLine) ||
109                  MiHasCmdTokenEndingAlpha(vTextLine));
110   vwbYesValid = vwbYesValid && MiHasCmd(vTextLine);
111   if (vwbYesValid) {
112     vwbCmdNotInCmdFactor = !HasCmdFactoryGotMiCmd(MiGetCmdData());
113     vwbYesValid = !vwbCmdNotInCmdFactor;
114   }
115
116   // Update command's meta data valid state
117   m_miCmdData.bCmdValid = vwbYesValid;
118
119   // Ok to return new updated command information
120   rwCmdData = MiGetCmdData();
121
122   return MIstatus::success;
123 }
124
125 //++
126 //------------------------------------------------------------------------------------
127 // Details: Establish whether the command name entered on the stdin stream is
128 // recognised by
129 //          the MI driver.
130 // Type:    Method.
131 // Args:    vCmd    - (R) Command information structure.
132 // Return:  bool  - True = yes command is recognised, false = command not
133 // recognised.
134 // Throws:  None.
135 //--
136 bool CMICmdInterpreter::HasCmdFactoryGotMiCmd(const SMICmdData &vCmd) const {
137   return m_rCmdFactory.CmdExist(vCmd.strMiCmd);
138 }
139
140 //++
141 //------------------------------------------------------------------------------------
142 // Details: Does the command entered match the criteria for a MI command format.
143 //          The format to validate against is 'nn-' where there can be 1 to n
144 //          digits.
145 //          I.e. '2-gdb-exit'.
146 //          Is the execution token present? The command token is entered into
147 //          the
148 //          command meta data structure whether correct or not for reporting or
149 //          later
150 //          command execution purposes.
151 // Type:    Method.
152 // Args:    vTextLine   - (R) Text data to interpret.
153 // Return:  bool  - True = yes command token present, false = command not
154 // recognised.
155 // Throws:  None.
156 //--
157 bool CMICmdInterpreter::MiHasCmdTokenEndingHyphen(
158     const CMIUtilString &vTextLine) {
159   // The hyphen is mandatory
160   const size_t nPos = vTextLine.find('-', 0);
161   if ((nPos == std::string::npos))
162     return false;
163
164   if (MiHasCmdTokenPresent(vTextLine)) {
165     const std::string strNum = vTextLine.substr(0, nPos);
166     if (!CMIUtilString(strNum).IsNumber())
167       return false;
168
169     m_miCmdData.strMiCmdToken = strNum;
170   }
171
172   m_miCmdData.bMIOldStyle = false;
173
174   return true;
175 }
176
177 //++
178 //------------------------------------------------------------------------------------
179 // Details: Does the command entered match the criteria for a MI command format.
180 //          The format to validate against is 'nnA' where there can be 1 to n
181 //          digits.
182 //          'A' represents any non numeric token. I.e. '1source .gdbinit'.
183 //          Is the execution token present? The command token is entered into
184 //          the
185 //          command meta data structure whether correct or not for reporting or
186 //          later
187 //          command execution purposes.
188 // Type:    Method.
189 // Args:    vTextLine   - (R) Text data to interpret.
190 // Return:  bool  - True = yes command token present, false = command not
191 // recognised.
192 // Throws:  None.
193 //--
194 bool CMICmdInterpreter::MiHasCmdTokenEndingAlpha(
195     const CMIUtilString &vTextLine) {
196   char cChar = vTextLine[0];
197   MIuint i = 0;
198   while (::isdigit(cChar) != 0) {
199     cChar = vTextLine[++i];
200   }
201   if (::isalpha(cChar) == 0)
202     return false;
203   if (i == 0)
204     return false;
205
206   const std::string strNum = vTextLine.substr(0, i);
207   m_miCmdData.strMiCmdToken = strNum.c_str();
208   m_miCmdData.bMIOldStyle = true;
209
210   return true;
211 }
212
213 //++
214 //------------------------------------------------------------------------------------
215 // Details: Does the command entered match the criteria for a MI command format.
216 //          Is the command token present before the hyphen?
217 // Type:    Method.
218 // Args:    vTextLine - (R) Text data to interpret.
219 // Return:  bool  - True = yes command token present, false = token not present.
220 // Throws:  None.
221 //--
222 bool CMICmdInterpreter::MiHasCmdTokenPresent(const CMIUtilString &vTextLine) {
223   const size_t nPos = vTextLine.find('-', 0);
224   return (nPos > 0);
225 }
226
227 //++
228 //------------------------------------------------------------------------------------
229 // Details: Does the command name entered match the criteria for a MI command
230 // format.
231 //          Is a recognised command present? The command name is entered into
232 //          the
233 //          command meta data structure whether correct or not for reporting or
234 //          later
235 //          command execution purposes. Command options is present are also put
236 //          into the
237 //          command meta data structure.
238 // Type:    Method.
239 // Args:    vTextLine   - (R) Command information structure.
240 // Return:  bool  - True = yes command name present, false = command not
241 // recognised.
242 // Throws:  None.
243 //--
244 bool CMICmdInterpreter::MiHasCmd(const CMIUtilString &vTextLine) {
245   size_t nPos = 0;
246   if (m_miCmdData.bMIOldStyle) {
247     char cChar = vTextLine[0];
248     size_t i = 0;
249     while (::isdigit(cChar) != 0) {
250       cChar = vTextLine[++i];
251     }
252     nPos = --i;
253   } else {
254     nPos = vTextLine.find('-', 0);
255   }
256
257   bool bFoundCmd = false;
258   const size_t nLen = vTextLine.length();
259   const size_t nPos2 = vTextLine.find(' ', nPos);
260   if (nPos2 != std::string::npos) {
261     if (nPos2 == nLen)
262       return false;
263     const CMIUtilString cmd =
264         CMIUtilString(vTextLine.substr(nPos + 1, nPos2 - nPos - 1));
265     if (cmd.empty())
266       return false;
267
268     m_miCmdData.strMiCmd = cmd;
269
270     if (nPos2 < nLen)
271       m_miCmdData.strMiCmdOption =
272           CMIUtilString(vTextLine.substr(nPos2 + 1, nLen - nPos2 - 1));
273
274     bFoundCmd = true;
275   } else {
276     const CMIUtilString cmd =
277         CMIUtilString(vTextLine.substr(nPos + 1, nLen - nPos - 1));
278     if (cmd.empty())
279       return false;
280     m_miCmdData.strMiCmd = cmd;
281     bFoundCmd = true;
282   }
283
284   if (bFoundCmd)
285     m_miCmdData.strMiCmdAll = vTextLine;
286
287   return bFoundCmd;
288 }
289
290 //++
291 //------------------------------------------------------------------------------------
292 // Details: Retrieve the just entered new command from stdin. It contains the
293 // command
294 //          name, number and any options.
295 // Type:    Method.
296 // Args:    vTextLine   - (R) Command information structure.
297 // Return:  SMICmdData & - Command meta data information/result/status.
298 // Throws:  None.
299 //--
300 const SMICmdData &CMICmdInterpreter::MiGetCmdData() const {
301   return m_miCmdData;
302 }