1 //===-- MICmdInterpreter.cpp ------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
11 #include "MICmdInterpreter.h"
12 #include "MICmdFactory.h"
15 //------------------------------------------------------------------------------------
16 // Details: CMICmdInterpreter constructor.
22 CMICmdInterpreter::CMICmdInterpreter()
23 : m_rCmdFactory(CMICmdFactory::Instance()) {}
26 //------------------------------------------------------------------------------------
27 // Details: CMICmdInterpreter destructor.
33 CMICmdInterpreter::~CMICmdInterpreter() { Shutdown(); }
36 //------------------------------------------------------------------------------------
37 // Details: Initialize resources for *this Command Interpreter.
40 // Return: MIstatus::success - Functional succeeded.
41 // MIstatus::failure - Functional failed.
44 bool CMICmdInterpreter::Initialize() {
45 m_clientUsageRefCnt++;
48 return MIstatus::success;
50 m_bInitialized = true;
52 return MIstatus::success;
56 //------------------------------------------------------------------------------------
57 // Details: Release resources for *this Command Interpreter.
60 // Return: MIstatus::success - Functional succeeded.
61 // MIstatus::failure - Functional failed.
64 bool CMICmdInterpreter::Shutdown() {
65 if (--m_clientUsageRefCnt > 0)
66 return MIstatus::success;
69 return MIstatus::success;
71 m_bInitialized = false;
73 return MIstatus::success;
77 //------------------------------------------------------------------------------------
78 // Details: Establish whether the text data is an MI format type command.
80 // Args: vTextLine - (R) Text data to interpret.
81 // vwbYesValid - (W) True = MI type command, false = not
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.
89 bool CMICmdInterpreter::ValidateIsMi(const CMIUtilString &vTextLine,
91 bool &vwbCmdNotInCmdFactor,
92 SMICmdData &rwCmdData) {
94 vwbCmdNotInCmdFactor = false;
97 if (vTextLine.empty())
98 return MIstatus::success;
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)
105 m_miCmdData.strMiCmd = vTextLine;
107 // The following change m_miCmdData as valid parts are identified
108 vwbYesValid = (MiHasCmdTokenEndingHyphen(vTextLine) ||
109 MiHasCmdTokenEndingAlpha(vTextLine));
110 vwbYesValid = vwbYesValid && MiHasCmd(vTextLine);
112 vwbCmdNotInCmdFactor = !HasCmdFactoryGotMiCmd(MiGetCmdData());
113 vwbYesValid = !vwbCmdNotInCmdFactor;
116 // Update command's meta data valid state
117 m_miCmdData.bCmdValid = vwbYesValid;
119 // Ok to return new updated command information
120 rwCmdData = MiGetCmdData();
122 return MIstatus::success;
126 //------------------------------------------------------------------------------------
127 // Details: Establish whether the command name entered on the stdin stream is
131 // Args: vCmd - (R) Command information structure.
132 // Return: bool - True = yes command is recognised, false = command not
136 bool CMICmdInterpreter::HasCmdFactoryGotMiCmd(const SMICmdData &vCmd) const {
137 return m_rCmdFactory.CmdExist(vCmd.strMiCmd);
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
145 // I.e. '2-gdb-exit'.
146 // Is the execution token present? The command token is entered into
148 // command meta data structure whether correct or not for reporting or
150 // command execution purposes.
152 // Args: vTextLine - (R) Text data to interpret.
153 // Return: bool - True = yes command token present, false = command not
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))
164 if (MiHasCmdTokenPresent(vTextLine)) {
165 const std::string strNum = vTextLine.substr(0, nPos);
166 if (!CMIUtilString(strNum).IsNumber())
169 m_miCmdData.strMiCmdToken = strNum;
172 m_miCmdData.bMIOldStyle = false;
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
182 // 'A' represents any non numeric token. I.e. '1source .gdbinit'.
183 // Is the execution token present? The command token is entered into
185 // command meta data structure whether correct or not for reporting or
187 // command execution purposes.
189 // Args: vTextLine - (R) Text data to interpret.
190 // Return: bool - True = yes command token present, false = command not
194 bool CMICmdInterpreter::MiHasCmdTokenEndingAlpha(
195 const CMIUtilString &vTextLine) {
196 char cChar = vTextLine[0];
198 while (::isdigit(cChar) != 0) {
199 cChar = vTextLine[++i];
201 if (::isalpha(cChar) == 0)
206 const std::string strNum = vTextLine.substr(0, i);
207 m_miCmdData.strMiCmdToken = strNum.c_str();
208 m_miCmdData.bMIOldStyle = true;
214 //------------------------------------------------------------------------------------
215 // Details: Does the command entered match the criteria for a MI command format.
216 // Is the command token present before the hyphen?
218 // Args: vTextLine - (R) Text data to interpret.
219 // Return: bool - True = yes command token present, false = token not present.
222 bool CMICmdInterpreter::MiHasCmdTokenPresent(const CMIUtilString &vTextLine) {
223 const size_t nPos = vTextLine.find('-', 0);
228 //------------------------------------------------------------------------------------
229 // Details: Does the command name entered match the criteria for a MI command
231 // Is a recognised command present? The command name is entered into
233 // command meta data structure whether correct or not for reporting or
235 // command execution purposes. Command options is present are also put
237 // command meta data structure.
239 // Args: vTextLine - (R) Command information structure.
240 // Return: bool - True = yes command name present, false = command not
244 bool CMICmdInterpreter::MiHasCmd(const CMIUtilString &vTextLine) {
246 if (m_miCmdData.bMIOldStyle) {
247 char cChar = vTextLine[0];
249 while (::isdigit(cChar) != 0) {
250 cChar = vTextLine[++i];
254 nPos = vTextLine.find('-', 0);
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) {
263 const CMIUtilString cmd =
264 CMIUtilString(vTextLine.substr(nPos + 1, nPos2 - nPos - 1));
268 m_miCmdData.strMiCmd = cmd;
271 m_miCmdData.strMiCmdOption =
272 CMIUtilString(vTextLine.substr(nPos2 + 1, nLen - nPos2 - 1));
276 const CMIUtilString cmd =
277 CMIUtilString(vTextLine.substr(nPos + 1, nLen - nPos - 1));
280 m_miCmdData.strMiCmd = cmd;
285 m_miCmdData.strMiCmdAll = vTextLine;
291 //------------------------------------------------------------------------------------
292 // Details: Retrieve the just entered new command from stdin. It contains the
294 // name, number and any options.
296 // Args: vTextLine - (R) Command information structure.
297 // Return: SMICmdData & - Command meta data information/result/status.
300 const SMICmdData &CMICmdInterpreter::MiGetCmdData() const {