/* * Copyright 2010, * François Bleibel, * Olivier Stasse, * * CNRS/AIST * * This file is part of dynamic-graph. * dynamic-graph is free software: you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation, either version 3 of * the License, or (at your option) any later version. * dynamic-graph is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. You should * have received a copy of the GNU Lesser General Public License along * with dynamic-graph. If not, see <http://www.gnu.org/licenses/>. */ #include <dynamic-graph/shell-procedure.h> #include <dynamic-graph/plugin-loader.h> #include <dynamic-graph/factory.h> #include <dynamic-graph/debug.h> #include <dynamic-graph/entity.h> #include <fstream> using namespace std; using namespace dynamicgraph; void ShellProcedure:: cmdStartProcedure( const std::string& cmdLine,std::istringstream& args,std::ostream& os ) { if( cmdLine == "help" ) { os << " - proc <name>" << "\t\t\t\tProcedure header." <<endl; return; } args>>procName; dgDEBUG(5)<<"Proc <" <<procName<<">"<<endl; currentProc.clear(); args >> ws; while( args.good() ) { std::string next; args>>next>>ws; currentProc.params.push_back(next); } } void ShellProcedure:: cmdContinueProcedure( const std::string& cmdLine,std::istringstream& args,std::ostream& os ) { if( cmdLine == "help" ) { os << " - -> cmd args..." << "\t\t\t\tProcedure body." <<endl; return; } std::string cmd2; args>>ws>>cmd2; dgDEBUG(5)<<"Proc <" <<procName<<">: "<<cmd2<<endl; Instruction ins; ins.cmd=cmd2; args >> ws; while( args.good() ) { std::string next; int param=-1; args>>next>>ws; for( unsigned int i=0;i<currentProc.params.size();++i ) { if( next==currentProc.params[i] ) { param=i; break; } } ins.args.push_back(next); ins.params.push_back( param ); } currentProc.instructions.push_back( ins ); } void ShellProcedure:: cmdEndProcedure( const std::string& cmdLine,std::istringstream& args,std::ostream& os ) { if( cmdLine == "help" ) { os << " - endproc..." << "\t\t\t\tProcedure end." <<endl; return; } dgDEBUG(5)<<"Proc <" <<procName<<">: endproc"<<endl; procedureList[ procName ] = currentProc; // std::string toto="toto"; // for( Procedure::iterator ins=procedureList[ toto ].begin(); // ins!=procedureList[ toto ].end(); ++ins ) // { // dgDEBUG(15) << "Proc <" << procName << "> : " // << ins->cmd << " -> " << ins->args <<endl; // } currentProc.clear(); if( g_shell.deregisterFunction( procName )) { os<< "Redefining proc <"<<procName<<">: procedure already defined. " << "Overwrite it."<<endl; } ShellFunctionRegisterer registration ( procName.c_str(),boost::bind(&ShellProcedure::cmdProcedure, this,procName,_1,_2,_3) ); } void ShellProcedure:: cmdProcedure( const std::string& procname, const std::string& cmdLine,std::istringstream& args,std::ostream& os ) { if( cmdLine == "help" ) { os<<" - "<<procname<<"\t\t\t\t\tUser-defined procedure"<<endl; args >> ws; if( args.good() ) { std::string argname; const unsigned int gc = args.tellg(); args >> argname; args.seekg(gc); args.clear(); if( procname==argname ) { /* if cmdline = "Help <procname>", then display * the proc instruction. */ ProcedureList::iterator pair = procedureList.find( argname ); if( pair==procedureList.end() ) { DG_THROW ExceptionFactory( ExceptionFactory::UNREFERED_FUNCTION, "Undefined procedure", ": procedure <%s> not defined.", argname.c_str() ); } Procedure & proc = pair->second; unsigned int cmdnum=1; for( std::list<Instruction>::iterator ins=proc.instructions.begin(); ins!=proc.instructions.end(); ++ins ) { os<<"\t#" <<cmdnum++<<" "<<ins->cmd; // <<" "<<ins->args <<endl; for( unsigned int i=0;i<ins->args.size();++i ) { os << " " << ins->args[i]; } os << endl; } } } return; } dgDEBUG(15) << " Calling procedure <" <<cmdLine<<"> " <<endl; ProcedureList::iterator pair = procedureList.find( cmdLine ); if( pair==procedureList.end() ) { DG_THROW ExceptionFactory( ExceptionFactory::UNREFERED_FUNCTION, "Undefined procedure", ": procedure <%s> not defined.",cmdLine.c_str() ); } /* You need a copy here, in case the proc is removed from the * list by itself: * % proc next * % -> proc next * % -> -> echo TOTO * % -> endproc * % endproc */ Procedure proc = pair->second; std::vector< std::string > paramValue; for( unsigned int i=0;i<proc.params.size();++i ) { args>>ws; if( args.good() ) { std::string next; args>>next>>ws; paramValue.push_back( next ); dgDEBUG(25) << "Args : <" << next << ">"<<endl; } else { paramValue.push_back(""); } } istringstream iss; ostringstream oss; for( std::list<Instruction>::iterator ins=proc.instructions.begin(); ins!=proc.instructions.end(); ++ins ) { dgDEBUG(15) << "Proc <" << cmdLine << "> : " << ins->cmd << endl; oss.clear(); oss.str(""); for( unsigned int i=0;i<ins->params.size();++i ) { int paramArg = ins->params[i]; if( paramArg==-1 ) oss << ins->args[i] << " "; else oss << paramValue[paramArg] << " "; } dgDEBUG(15) << " Args = " << oss.str() << endl; iss.str(oss.str()); iss.clear(); g_shell.cmd(ins->cmd,iss,os); } } void ShellProcedure:: cmdFor( const std::string& cmdLine,std::istringstream& args,std::ostream& os ) { if( cmdLine == "help" ) { os << " - for 1 5 instruction "<<endl; return; } std::string cmd2,idx; int istart,iend; { stringstream oss; args >> cmd2; oss.str( cmd2 ); const unsigned int SIZE = 32; char b1[SIZE],b2[SIZE],b3[SIZE]; oss.getline( b1,SIZE,'=' ); oss.getline( b2,SIZE,':' ); oss.getline( b3,SIZE ); dgDEBUG(15) << b1 << "/" << b2 << "/" << b3 << endl; idx = b1; istart = atoi(b2); iend = atoi(b3); args >> cmd2; dgDEBUG(15) << "FOR <" << idx << "> = " << istart << " TO " << iend << " DO " << cmd2 <<endl; } string argsstr; { const unsigned int SIZE = 1024; char buffer[SIZE]; args.getline( buffer,SIZE ); argsstr = buffer; } for( int i=istart;i<=iend;++i ) { istringstream iss; stringstream oss; std::string insp; istringstream issargs( argsstr ); while( issargs.good() ) { issargs >> insp; if( insp == idx ) { oss << i << " "; } else { oss<<insp<< " "; } } iss.str( oss.str() ); g_shell.cmd(cmd2,iss,os); } } ShellProcedure sotShellProceduror; extern "C" { ShellFunctionRegisterer regFun1 ( "proc",boost::bind(&ShellProcedure::cmdStartProcedure, &sotShellProceduror,_1,_2,_3) ); ShellFunctionRegisterer regFun2 ( "->",boost::bind(&ShellProcedure::cmdContinueProcedure, &sotShellProceduror,_1,_2,_3) ); ShellFunctionRegisterer regFun3 ( "endproc",boost::bind(&ShellProcedure::cmdEndProcedure, &sotShellProceduror,_1,_2,_3) ); ShellFunctionRegisterer regFun4 ( "for",boost::bind(&ShellProcedure::cmdFor, _1,_2,_3) ); }