forked from OSchip/llvm-project
303 lines
9.4 KiB
C++
303 lines
9.4 KiB
C++
//===-- MICmdInterpreter.cpp ------------------------------------*- C++ -*-===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// In-house headers:
|
|
#include "MICmdInterpreter.h"
|
|
#include "MICmdFactory.h"
|
|
|
|
//++
|
|
//------------------------------------------------------------------------------------
|
|
// Details: CMICmdInterpreter constructor.
|
|
// Type: Method.
|
|
// Args: None.
|
|
// Return: None.
|
|
// Throws: None.
|
|
//--
|
|
CMICmdInterpreter::CMICmdInterpreter()
|
|
: m_rCmdFactory(CMICmdFactory::Instance()) {}
|
|
|
|
//++
|
|
//------------------------------------------------------------------------------------
|
|
// Details: CMICmdInterpreter destructor.
|
|
// Type: Overridable.
|
|
// Args: None.
|
|
// Return: None.
|
|
// Throws: None.
|
|
//--
|
|
CMICmdInterpreter::~CMICmdInterpreter() { Shutdown(); }
|
|
|
|
//++
|
|
//------------------------------------------------------------------------------------
|
|
// Details: Initialize resources for *this Command Interpreter.
|
|
// Type: Method.
|
|
// Args: None.
|
|
// Return: MIstatus::success - Functional succeeded.
|
|
// MIstatus::failure - Functional failed.
|
|
// Throws: None.
|
|
//--
|
|
bool CMICmdInterpreter::Initialize() {
|
|
m_clientUsageRefCnt++;
|
|
|
|
if (m_bInitialized)
|
|
return MIstatus::success;
|
|
|
|
m_bInitialized = true;
|
|
|
|
return MIstatus::success;
|
|
}
|
|
|
|
//++
|
|
//------------------------------------------------------------------------------------
|
|
// Details: Release resources for *this Command Interpreter.
|
|
// Type: Method.
|
|
// Args: None.
|
|
// Return: MIstatus::success - Functional succeeded.
|
|
// MIstatus::failure - Functional failed.
|
|
// Throws: None.
|
|
//--
|
|
bool CMICmdInterpreter::Shutdown() {
|
|
if (--m_clientUsageRefCnt > 0)
|
|
return MIstatus::success;
|
|
|
|
if (!m_bInitialized)
|
|
return MIstatus::success;
|
|
|
|
m_bInitialized = false;
|
|
|
|
return MIstatus::success;
|
|
}
|
|
|
|
//++
|
|
//------------------------------------------------------------------------------------
|
|
// Details: Establish whether the text data is an MI format type command.
|
|
// Type: Method.
|
|
// Args: vTextLine - (R) Text data to interpret.
|
|
// vwbYesValid - (W) True = MI type command, false = not
|
|
// recognised.
|
|
// vwbCmdNotInCmdFactor - (W) True = MI command not found in the
|
|
// command factory, false = recognised.
|
|
// Return: MIstatus::success - Functional succeeded.
|
|
// MIstatus::failure - Functional failed.
|
|
// Throws: None.
|
|
//--
|
|
bool CMICmdInterpreter::ValidateIsMi(const CMIUtilString &vTextLine,
|
|
bool &vwbYesValid,
|
|
bool &vwbCmdNotInCmdFactor,
|
|
SMICmdData &rwCmdData) {
|
|
vwbYesValid = false;
|
|
vwbCmdNotInCmdFactor = false;
|
|
rwCmdData.Clear();
|
|
|
|
if (vTextLine.empty())
|
|
return MIstatus::success;
|
|
|
|
// MI format is [cmd #]-[command name]<space>[command arg(s)]
|
|
// i.e. 1-file-exec-and-symbols --thread-group i1 DEVICE_EXECUTABLE
|
|
// 5-data-evaluate-expression --thread 1 --frame 0 *(argv)
|
|
|
|
m_miCmdData.Clear();
|
|
m_miCmdData.strMiCmd = vTextLine;
|
|
|
|
// The following change m_miCmdData as valid parts are identified
|
|
vwbYesValid = (MiHasCmdTokenEndingHyphen(vTextLine) ||
|
|
MiHasCmdTokenEndingAlpha(vTextLine));
|
|
vwbYesValid = vwbYesValid && MiHasCmd(vTextLine);
|
|
if (vwbYesValid) {
|
|
vwbCmdNotInCmdFactor = !HasCmdFactoryGotMiCmd(MiGetCmdData());
|
|
vwbYesValid = !vwbCmdNotInCmdFactor;
|
|
}
|
|
|
|
// Update command's meta data valid state
|
|
m_miCmdData.bCmdValid = vwbYesValid;
|
|
|
|
// Ok to return new updated command information
|
|
rwCmdData = MiGetCmdData();
|
|
|
|
return MIstatus::success;
|
|
}
|
|
|
|
//++
|
|
//------------------------------------------------------------------------------------
|
|
// Details: Establish whether the command name entered on the stdin stream is
|
|
// recognised by
|
|
// the MI driver.
|
|
// Type: Method.
|
|
// Args: vCmd - (R) Command information structure.
|
|
// Return: bool - True = yes command is recognised, false = command not
|
|
// recognised.
|
|
// Throws: None.
|
|
//--
|
|
bool CMICmdInterpreter::HasCmdFactoryGotMiCmd(const SMICmdData &vCmd) const {
|
|
return m_rCmdFactory.CmdExist(vCmd.strMiCmd);
|
|
}
|
|
|
|
//++
|
|
//------------------------------------------------------------------------------------
|
|
// Details: Does the command entered match the criteria for a MI command format.
|
|
// The format to validate against is 'nn-' where there can be 1 to n
|
|
// digits.
|
|
// I.e. '2-gdb-exit'.
|
|
// Is the execution token present? The command token is entered into
|
|
// the
|
|
// command meta data structure whether correct or not for reporting or
|
|
// later
|
|
// command execution purposes.
|
|
// Type: Method.
|
|
// Args: vTextLine - (R) Text data to interpret.
|
|
// Return: bool - True = yes command token present, false = command not
|
|
// recognised.
|
|
// Throws: None.
|
|
//--
|
|
bool CMICmdInterpreter::MiHasCmdTokenEndingHyphen(
|
|
const CMIUtilString &vTextLine) {
|
|
// The hyphen is mandatory
|
|
const size_t nPos = vTextLine.find('-', 0);
|
|
if ((nPos == std::string::npos))
|
|
return false;
|
|
|
|
if (MiHasCmdTokenPresent(vTextLine)) {
|
|
const std::string strNum = vTextLine.substr(0, nPos);
|
|
if (!CMIUtilString(strNum).IsNumber())
|
|
return false;
|
|
|
|
m_miCmdData.strMiCmdToken = strNum;
|
|
}
|
|
|
|
m_miCmdData.bMIOldStyle = false;
|
|
|
|
return true;
|
|
}
|
|
|
|
//++
|
|
//------------------------------------------------------------------------------------
|
|
// Details: Does the command entered match the criteria for a MI command format.
|
|
// The format to validate against is 'nnA' where there can be 1 to n
|
|
// digits.
|
|
// 'A' represents any non numeric token. I.e. '1source .gdbinit'.
|
|
// Is the execution token present? The command token is entered into
|
|
// the
|
|
// command meta data structure whether correct or not for reporting or
|
|
// later
|
|
// command execution purposes.
|
|
// Type: Method.
|
|
// Args: vTextLine - (R) Text data to interpret.
|
|
// Return: bool - True = yes command token present, false = command not
|
|
// recognised.
|
|
// Throws: None.
|
|
//--
|
|
bool CMICmdInterpreter::MiHasCmdTokenEndingAlpha(
|
|
const CMIUtilString &vTextLine) {
|
|
char cChar = vTextLine[0];
|
|
MIuint i = 0;
|
|
while (::isdigit(cChar) != 0) {
|
|
cChar = vTextLine[++i];
|
|
}
|
|
if (::isalpha(cChar) == 0)
|
|
return false;
|
|
if (i == 0)
|
|
return false;
|
|
|
|
const std::string strNum = vTextLine.substr(0, i);
|
|
m_miCmdData.strMiCmdToken = strNum.c_str();
|
|
m_miCmdData.bMIOldStyle = true;
|
|
|
|
return true;
|
|
}
|
|
|
|
//++
|
|
//------------------------------------------------------------------------------------
|
|
// Details: Does the command entered match the criteria for a MI command format.
|
|
// Is the command token present before the hyphen?
|
|
// Type: Method.
|
|
// Args: vTextLine - (R) Text data to interpret.
|
|
// Return: bool - True = yes command token present, false = token not present.
|
|
// Throws: None.
|
|
//--
|
|
bool CMICmdInterpreter::MiHasCmdTokenPresent(const CMIUtilString &vTextLine) {
|
|
const size_t nPos = vTextLine.find('-', 0);
|
|
return (nPos > 0);
|
|
}
|
|
|
|
//++
|
|
//------------------------------------------------------------------------------------
|
|
// Details: Does the command name entered match the criteria for a MI command
|
|
// format.
|
|
// Is a recognised command present? The command name is entered into
|
|
// the
|
|
// command meta data structure whether correct or not for reporting or
|
|
// later
|
|
// command execution purposes. Command options is present are also put
|
|
// into the
|
|
// command meta data structure.
|
|
// Type: Method.
|
|
// Args: vTextLine - (R) Command information structure.
|
|
// Return: bool - True = yes command name present, false = command not
|
|
// recognised.
|
|
// Throws: None.
|
|
//--
|
|
bool CMICmdInterpreter::MiHasCmd(const CMIUtilString &vTextLine) {
|
|
size_t nPos = 0;
|
|
if (m_miCmdData.bMIOldStyle) {
|
|
char cChar = vTextLine[0];
|
|
size_t i = 0;
|
|
while (::isdigit(cChar) != 0) {
|
|
cChar = vTextLine[++i];
|
|
}
|
|
nPos = --i;
|
|
} else {
|
|
nPos = vTextLine.find('-', 0);
|
|
}
|
|
|
|
bool bFoundCmd = false;
|
|
const size_t nLen = vTextLine.length();
|
|
const size_t nPos2 = vTextLine.find(' ', nPos);
|
|
if (nPos2 != std::string::npos) {
|
|
if (nPos2 == nLen)
|
|
return false;
|
|
const CMIUtilString cmd =
|
|
CMIUtilString(vTextLine.substr(nPos + 1, nPos2 - nPos - 1));
|
|
if (cmd.empty())
|
|
return false;
|
|
|
|
m_miCmdData.strMiCmd = cmd;
|
|
|
|
if (nPos2 < nLen)
|
|
m_miCmdData.strMiCmdOption =
|
|
CMIUtilString(vTextLine.substr(nPos2 + 1, nLen - nPos2 - 1));
|
|
|
|
bFoundCmd = true;
|
|
} else {
|
|
const CMIUtilString cmd =
|
|
CMIUtilString(vTextLine.substr(nPos + 1, nLen - nPos - 1));
|
|
if (cmd.empty())
|
|
return false;
|
|
m_miCmdData.strMiCmd = cmd;
|
|
bFoundCmd = true;
|
|
}
|
|
|
|
if (bFoundCmd)
|
|
m_miCmdData.strMiCmdAll = vTextLine;
|
|
|
|
return bFoundCmd;
|
|
}
|
|
|
|
//++
|
|
//------------------------------------------------------------------------------------
|
|
// Details: Retrieve the just entered new command from stdin. It contains the
|
|
// command
|
|
// name, number and any options.
|
|
// Type: Method.
|
|
// Args: vTextLine - (R) Command information structure.
|
|
// Return: SMICmdData & - Command meta data information/result/status.
|
|
// Throws: None.
|
|
//--
|
|
const SMICmdData &CMICmdInterpreter::MiGetCmdData() const {
|
|
return m_miCmdData;
|
|
}
|