forked from OSchip/llvm-project
302 lines
9.1 KiB
C++
302 lines
9.1 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.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//++
|
|
// File: MICmdInterpreter.cpp
|
|
//
|
|
// Overview: CMICmdInterpreter implementation.
|
|
//
|
|
// Environment: Compilers: Visual C++ 12.
|
|
// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
|
|
// Libraries: See MIReadmetxt.
|
|
//
|
|
// Copyright: None.
|
|
//--
|
|
|
|
// In-house headers:
|
|
#include "MICmdInterpreter.h"
|
|
#include "MICmdFactory.h"
|
|
|
|
//++ ------------------------------------------------------------------------------------
|
|
// Details: CMICmdInterpreter constructor.
|
|
// Type: Method.
|
|
// Args: None.
|
|
// Return: None.
|
|
// Throws: None.
|
|
//--
|
|
CMICmdInterpreter::CMICmdInterpreter( void )
|
|
: m_rCmdFactory( CMICmdFactory::Instance() )
|
|
{
|
|
}
|
|
|
|
//++ ------------------------------------------------------------------------------------
|
|
// Details: CMICmdInterpreter destructor.
|
|
// Type: Overridable.
|
|
// Args: None.
|
|
// Return: None.
|
|
// Throws: None.
|
|
//--
|
|
CMICmdInterpreter::~CMICmdInterpreter( void )
|
|
{
|
|
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( void )
|
|
{
|
|
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( void )
|
|
{
|
|
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 indentified
|
|
vwbYesValid = (MiHasCmdTokenEndingHypthen( 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::MiHasCmdTokenEndingHypthen( const CMIUtilString & vTextLine )
|
|
{
|
|
// The hythen is mandatory
|
|
const MIint nPos = vTextLine.find( "-", 0 );
|
|
if( (nPos == (MIint) std::string::npos) )
|
|
return false;
|
|
|
|
if( MiHasCmdTokenPresent( vTextLine ) )
|
|
{
|
|
const std::string strNum = vTextLine.substr( 0, nPos );
|
|
if( !CMIUtilString( strNum.c_str() ).IsNumber() )
|
|
return false;
|
|
|
|
m_miCmdData.strMiCmdToken = strNum.c_str();
|
|
}
|
|
|
|
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 )
|
|
{
|
|
MIchar 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 hypen?
|
|
// 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 MIint nPos = vTextLine.find( "-", 0 );
|
|
return (nPos > 0);
|
|
}
|
|
|
|
//++ ------------------------------------------------------------------------------------
|
|
// Details: Does the command name entered match the criteria for a MI command format.
|
|
// Is a recogised 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 )
|
|
{
|
|
MIint nPos = 0;
|
|
if( m_miCmdData.bMIOldStyle )
|
|
{
|
|
char cChar = vTextLine[ 0 ];
|
|
MIuint i = 0;
|
|
while( ::isdigit( cChar ) != 0 )
|
|
{
|
|
cChar = vTextLine[ ++i ];
|
|
}
|
|
nPos = --i;
|
|
}
|
|
else
|
|
{
|
|
nPos = vTextLine.find( "-", 0 );
|
|
}
|
|
|
|
bool bFoundCmd = false;
|
|
const MIint nLen = vTextLine.length();
|
|
const MIint nPos2 = vTextLine.find( " ", nPos );
|
|
if( nPos2 != (MIint) std::string::npos )
|
|
{
|
|
if( nPos2 == nLen )
|
|
return false;
|
|
const CMIUtilString cmd = CMIUtilString( vTextLine.substr( nPos + 1, nPos2 - nPos - 1 ).c_str() );
|
|
if( cmd.empty() )
|
|
return false;
|
|
|
|
m_miCmdData.strMiCmd = cmd;
|
|
|
|
if( nPos2 < nLen )
|
|
m_miCmdData.strMiCmdOption = CMIUtilString( vTextLine.substr( nPos2 + 1, nLen - nPos2 - 1 ).c_str() );
|
|
|
|
bFoundCmd = true;
|
|
}
|
|
else
|
|
{
|
|
const CMIUtilString cmd = CMIUtilString( vTextLine.substr( nPos + 1, nLen - nPos - 1 ).c_str() );
|
|
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( void ) const
|
|
{
|
|
return m_miCmdData;
|
|
}
|
|
|