aboutsummaryrefslogtreecommitdiff
path: root/tools/lldb-mi/MICmdInterpreter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tools/lldb-mi/MICmdInterpreter.cpp')
-rw-r--r--tools/lldb-mi/MICmdInterpreter.cpp301
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;
+}
+