Files
EgtGeneral/CmdParser.cpp
T
Dario Sassi e8a7eaa2ac EgtGeneral :
- aggiunta a CmdParser GetIdParam.
2014-04-10 17:34:55 +00:00

533 lines
15 KiB
C++

//----------------------------------------------------------------------------
// EgalTech 2013-2013
//----------------------------------------------------------------------------
// File : CmdParser.cpp Data : 25.11.13 Versione : 1.3a1
// Contenuto : Implementazione della classe CCmdParser.
//
//
//
// Modifiche : 19.01.13 DS Creazione modulo.
//
//
//----------------------------------------------------------------------------
//--------------------------- Include ----------------------------------------
#include "stdafx.h"
#include "CmdParser.h"
#include "DllMain.h"
#include "/EgtDev/Include/EgnStringUtils.h"
#include "/EgtDev/Include/EGnFileUtils.h"
#include "/EgtDev/Include/EGnFileCompare.h"
#include "/EgtDev/Include/EgnCmdExecutor.h"
#include "/EgtDev/Include/EgtILogger.h"
#include <iostream>
using namespace std ;
//----------------------------------------------------------------------------
ICmdParser*
CreateCmdParser( void)
{
return static_cast<ICmdParser*> ( new CmdParser) ;
}
//----------------------------------------------------------------------------
CmdParser::CmdParser( void)
{
m_nLev = 0 ;
// assegno chiavi a funzioni di esecuzione
m_ExecMgr.Init( 16) ;
m_ExecMgr.Insert( "COUNTER", &CmdParser::ExecuteCounter) ;
m_ExecMgr.Insert( "DIR", &CmdParser::ExecuteDir) ;
m_ExecMgr.Insert( "FILE", &CmdParser::ExecuteFile) ;
m_ExecMgr.Insert( "PAUSE", &CmdParser::ExecutePause) ;
m_ExecMgr.Insert( "RESET", &CmdParser::ExecuteReset) ;
m_ExecMgr.Insert( "RUN", &CmdParser::ExecuteRun) ;
m_ExecMgr.Insert( "SET", &CmdParser::ExecuteSet) ;
}
//----------------------------------------------------------------------------
CmdParser::~CmdParser( void)
{
}
//----------------------------------------------------------------------------
bool
CmdParser::SetExecutor( ICmdExecutor* pCmdExec)
{
// pulisco lista esecutori
m_CmdExecList.clear() ;
// verifico la validità dell'esecutore
if ( pCmdExec == nullptr)
return false ;
// salvo il riferimento all'esecutore e mi registro
try { m_CmdExecList.push_back( pCmdExec) ; }
catch(...) { return false ; }
pCmdExec->SetCmdParser( this) ;
return true ;
}
//----------------------------------------------------------------------------
bool
CmdParser::AddExecutor( ICmdExecutor* pCmdExec)
{
// verifico la validità dell'esecutore
if ( pCmdExec == nullptr)
return false ;
// salvo il riferimento all'esecutore e mi registro
try { m_CmdExecList.push_back( pCmdExec) ; }
catch(...) { return false ; }
pCmdExec->SetCmdParser( this) ;
return true ;
}
//----------------------------------------------------------------------------
bool
CmdParser::Init( void)
{
// reimposto le variabili
ResetAllVariables() ;
// imposto il livello di esecuzione iniziale
m_nLev = 0 ;
return true ;
}
//----------------------------------------------------------------------------
bool
CmdParser::Run( const std::string& sCmdFile, bool bIsolated)
{
bool bOk ;
string sOut ;
string sLine ;
string sCmd ;
string sParams ;
string sDummy ;
NameMap CurrNameMap ;
CmdScanner TheScanner ;
// se richiesta esecuzione isolata, faccio una copia dello stato delle variabili
if ( bIsolated)
CurrNameMap = m_NameMap ;
// log di inizio file
sOut = GetInitSpaces() + "--- Start : " + sCmdFile + " ---" ;
LOG_INFO( GetEGnLogger(), sOut.c_str())
// inizializzo lo scanner
bOk = TheScanner.Init( sCmdFile) ;
if ( ! bOk) {
sOut = GetInitSpaces() + "Error opening command file" ;
LOG_ERROR( GetEGnLogger(), sOut.c_str())
}
// interpretazione dei comandi del file
while ( bOk && TheScanner.GetLine( sLine)) {
// elimino gli spazi all'inizio e alla fine
Trim( sLine) ;
// separo comando e parametri
SplitFirst( sLine, "(", sCmd, sParams) ;
// elimino dai parametri tutto quanto dopo ultima parentesi chiusa
SplitLast( sParams, ")", sParams, sDummy) ;
// deve esserci un comando e deve essere eseguito correttamente
if ( sCmd.empty() || ! ExecCommand( sCmd, sParams)) {
bOk = false ;
sOut = GetInitSpaces() + "Error on line (" + ToString( TheScanner.GetCurrLineNbr()) + ") : " + sLine ;
LOG_ERROR( GetEGnLogger(), sOut.c_str())
}
}
// log di fine file
if ( bOk) {
sOut = GetInitSpaces() + "--- End ---" ;
LOG_INFO( GetEGnLogger(), sOut.c_str())
}
else {
sOut = GetInitSpaces() + "--- Stop : error ---" ;
LOG_ERROR( GetEGnLogger(), sOut.c_str())
}
// se richiesta esecuzione isolata, ripristino lo stato originale delle variabili
if ( bIsolated)
m_NameMap = CurrNameMap ;
return bOk ;
}
//----------------------------------------------------------------------------
bool
CmdParser::ExecLine( const string& sCmdLine, bool bIsolated)
{
NameMap CurrNameMap ;
// se richiesta esecuzione isolata, faccio una copia dello stato delle variabili
if ( bIsolated)
CurrNameMap = m_NameMap ;
// elimino gli spazi all'inizio e alla fine
string sLine = sCmdLine ;
Trim( sLine) ;
// separo comando e parametri
string sCmd, sParams ;
SplitFirst( sLine, "(", sCmd, sParams) ;
// elimino dai parametri tutto quanto dopo ultima parentesi chiusa
string sDummy ;
SplitLast( sParams, ")", sParams, sDummy) ;
// deve esserci un comando e deve essere eseguito correttamente
bool bOk = true ;
if ( sCmd.empty() || ! ExecCommand( sCmd, sParams)) {
bOk = false ;
string sOut = GetInitSpaces() + "Error on line : " + sCmdLine ;
LOG_ERROR( GetEGnLogger(), sOut.c_str())
}
// se richiesta esecuzione isolata, ripristino lo stato originale delle variabili
if ( bIsolated)
m_NameMap = CurrNameMap ;
return bOk ;
}
//----------------------------------------------------------------------------
bool
CmdParser::AddVariable( const std::string& sName, int nVal)
{
return ( m_NameMap.insert( NameMap::value_type( sName, nVal)).second) ;
}
//----------------------------------------------------------------------------
bool
CmdParser::SetVariable( const std::string& sName, int nVal)
{
NameMap::iterator Iter ;
Iter = m_NameMap.find( sName) ;
if ( Iter != m_NameMap.end()) {
Iter->second = nVal ;
return true ;
}
return false ;
}
//----------------------------------------------------------------------------
bool
CmdParser::GetVariable( const std::string& sName, int& nVal)
{
NameMap::const_iterator Iter ;
Iter = m_NameMap.find( sName) ;
if ( Iter != m_NameMap.end()) {
nVal = Iter->second ;
return true ;
}
return false ;
}
//----------------------------------------------------------------------------
bool
CmdParser::RemoveVariable( const std::string& sName)
{
return ( m_NameMap.erase( sName) > 0) ;
}
//----------------------------------------------------------------------------
bool
CmdParser::ResetAllVariables( void)
{
// pulisco e imposto dimensioni mappa dei nomi di variabili
m_NameMap.clear() ;
m_NameMap.rehash( 100) ;
// installo variabili standard
PCmdExecList::iterator Iter ;
for ( Iter = m_CmdExecList.begin() ; Iter != m_CmdExecList.end() ; ++ Iter) {
if ( (*Iter) == nullptr ||
! (*Iter)->AddStandardVariables())
return false ;
}
return true ;
}
//----------------------------------------------------------------------------
int
CmdParser::GetIdParam( const std::string& sParam, bool bNewAllowed)
{
int nVal ;
// se nome di identificatore numerico
if ( sParam[0] == '$') {
// se variabile già definita, ne restituisco il valore
if ( GetVariable( sParam, nVal))
return nVal ;
// se ammessa nuova definizione, provo ad inserirlo
else if ( bNewAllowed &&
AddVariable( sParam, CMD_ID_NULL))
return CMD_ID_NULL ;
// altrimenti errore
else
return CMD_ID_ERROR ;
}
// se identificatore numerico
else if ( FromString( sParam, nVal))
return nVal ;
// altrimenti errore
else
return CMD_ID_ERROR ;
}
//----------------------------------------------------------------------------
const string
CmdParser::GetInitSpaces( void)
{
string sIni ;
for ( int i = 0 ; i < m_nLev ; ++ i)
sIni += " " ;
return sIni ;
}
//----------------------------------------------------------------------------
bool
CmdParser::ExecCommand( const string& sCmd, const string& sParams)
{
// divido il comando e lo normalizzo
string sCmd1, sCmd2 ;
SplitFirst( sCmd, ".", sCmd1, sCmd2) ;
Trim( sCmd1) ;
ToUpper( sCmd1) ;
Trim( sCmd2) ;
ToUpper( sCmd2) ;
// divido i parametri
STRVECTOR vsParams ;
Tokenize( sParams, ",", "(", ")", vsParams) ;
STRVECTOR::iterator Iter ;
for ( Iter = vsParams.begin() ; Iter != vsParams.end() ; ++ Iter)
Trim( (*Iter)) ;
// output di debug
string sOut = GetInitSpaces() + sCmd1 ;
if ( ! sCmd2.empty())
sOut += "." + sCmd2 ;
sOut += "( " ;
for ( Iter = vsParams.begin() ; Iter != vsParams.end() ; ++ Iter) {
if ( Iter != vsParams.begin())
sOut += ", " ;
sOut += *Iter ;
}
sOut += ")" ;
LOG_DBG_INFO( GetEGnLogger(), sOut.c_str())
// eseguo il comando cercando nell'esecutore di comandi locale
int nRes = m_ExecMgr.Execute( *this, sCmd1, sCmd2, vsParams) ;
if ( nRes != ER_MISSING)
return ( nRes == ER_OK) ;
// eseguo il comando cercando negli esecutori di comandi installati
PCmdExecList::iterator IterCEL ;
for ( IterCEL = m_CmdExecList.begin() ; IterCEL != m_CmdExecList.end() ; ++ IterCEL) {
if ( (*IterCEL) == nullptr)
return false ;
nRes = (*IterCEL)->Execute( sCmd1, sCmd2, vsParams) ;
if ( nRes != ER_MISSING)
return ( nRes == ER_OK) ;
}
return false ;
}
//----------------------------------------------------------------------------
bool
CmdParser::ExecuteCounter( const string& sCmd2, const STRVECTOR& vsParams)
{
// avvio il counter
if ( sCmd2 == "START") {
m_Counter.Start() ;
return true ;
}
// fermo il counter ed emetto i risultati
else if ( sCmd2 == "STOP") {
m_Counter.Stop() ;
string sOut = " " + ( ( vsParams.size() >= 1) ? vsParams[0] : "ExecTime =") ;
sOut += " " + ToString( m_Counter.GetTime(), 2) + " ms" ;
LOG_INFO( GetEGnLogger(), sOut.c_str())
return true ;
}
return false ;
}
//----------------------------------------------------------------------------
bool
CmdParser::ExecuteDir( const string& sCmd2, const STRVECTOR& vsParams)
{
// analisi ed esecuzione dei comandi
if ( sCmd2 == "EMPTY") {
// 1 parametro : nome direttorio da svuotare
if ( vsParams.size() != 1)
return false ;
// svuoto il direttorio
EmptyDirectory( vsParams[0]) ;
return true ;
}
return false ;
}
//----------------------------------------------------------------------------
bool
CmdParser::ExecuteFile( const string& sCmd2, const STRVECTOR& vsParams)
{
// cancellazione file
if ( sCmd2 == "DEL") {
// 1 parametro : file
if ( vsParams.size() != 1)
return false ;
// eseguo la cancellazione
EraseFile( vsParams[0]) ;
return true ;
}
// confronto tra file
else if ( sCmd2 == "CMP") {
// 4 parametri : file1, file2, inizio commento, file diff
if ( vsParams.size() != 4)
return false ;
// eseguo il confronto
TextFileCompare( vsParams[0], vsParams[1], vsParams[2], vsParams[3]) ;
return true ;
}
return false ;
}
//----------------------------------------------------------------------------
bool
CmdParser::ExecutePause( const string& sCmd2, const STRVECTOR& vsParams)
{
if ( sCmd2.empty()) {
const int MIN_TIME = 0 ;
const int MAX_TIME = 10000 ;
// 1 parametro : durata della pausa in ms
if ( vsParams.size() != 1)
return false ;
// tempo di attesa
int nTime ;
if ( ! FromString( vsParams[0], nTime))
return false ;
if ( nTime < MIN_TIME)
nTime = MIN_TIME ;
else if ( nTime > MAX_TIME)
nTime = MAX_TIME ;
// eseguo
Sleep( nTime) ;
return true ;
}
return false ;
}
//----------------------------------------------------------------------------
bool
CmdParser::ExecuteReset( const string& sCmd2, const STRVECTOR& vsParams)
{
// ripristino dell'ambiente di esecuzione
if ( sCmd2 == "ALL") {
return ResetAllVariables() ;
}
// cancellazione di un identificativo
else if ( sCmd2.empty()) {
// 1 parametro ( Nome/i)
if ( vsParams.size() != 1)
return false ;
// recupero lista nomi
STRVECTOR vsNames ;
if ( ! GetNamesParam( vsParams[0], vsNames))
return false ;
// eseguo cancellazioni
STRVECTOR::iterator Iter ;
for ( Iter = vsNames.begin() ; Iter != vsNames.end() ; ++Iter)
RemoveVariable( *Iter) ;
return true ;
}
return false ;
}
//----------------------------------------------------------------------------
bool
CmdParser::ExecuteRun( const string& sCmd2, const STRVECTOR& vsParams)
{
if ( sCmd2.empty()) {
// almeno 1 parametro : nome file di script da eseguire
if ( vsParams.size() < 1)
return false ;
// se esiste 2° parametro è flag di ignora errori
bool bSkipErrors = false ;
if ( vsParams.size() >= 2)
FromString( vsParams[1], bSkipErrors) ;
// controllo massimo numero di annidamenti
if ( m_nLev >= 5)
return false ;
// esecuzione comando
++ m_nLev ;
bool bOk = Run( vsParams[0]) ;
-- m_nLev ;
return ( bOk || bSkipErrors) ;
}
return false ;
}
//----------------------------------------------------------------------------
bool
CmdParser::ExecuteSet( const string& sCmd2, const STRVECTOR& vsParams)
{
if ( sCmd2.empty()) {
// 2 parametri ( Nome, Valore)
if ( vsParams.size() != 2)
return false ;
// recupero il valore
int nVal ;
if ( ! FromString( vsParams[1], nVal))
return false ;
// eseguo
if ( SetVariable( vsParams[0], nVal))
return true ;
else
return AddVariable( vsParams[0], nVal) ;
}
return false ;
}
//----------------------------------------------------------------------------
bool
CmdParser::GetNamesParam( const std::string& sParam, STRVECTOR& vsNames)
{
STRVECTOR::iterator Iter ;
// divido in parti
Tokenize( sParam, ",", vsNames) ;
for ( Iter = vsNames.begin() ; Iter != vsNames.end() ; ++Iter)
Trim( (*Iter), " \t\r\n()") ;
return true ;
}