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