diff options
Diffstat (limited to 'tools/lldb-mi/MICmdInterpreter.cpp')
-rw-r--r-- | tools/lldb-mi/MICmdInterpreter.cpp | 301 |
1 files changed, 301 insertions, 0 deletions
diff --git a/tools/lldb-mi/MICmdInterpreter.cpp b/tools/lldb-mi/MICmdInterpreter.cpp new file mode 100644 index 000000000000..dd5b2818705c --- /dev/null +++ b/tools/lldb-mi/MICmdInterpreter.cpp @@ -0,0 +1,301 @@ +//===-- 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; +} + |