| //===-- 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; |
| } |
| |