00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 #include "ParserScriptingAccess.hpp"
00041 #include "StatementProcessor.hpp"
00042 #include "Parser.hpp"
00043 #include "Logger.hpp"
00044 #include "TaskContext.hpp"
00045 #include "Method.hpp"
00046 #include "Command.hpp"
00047 #include "ProgramProcessor.hpp"
00048 #include "StateMachineProcessor.hpp"
00049 #include <sstream>
00050 #include <fstream>
00051
00052 namespace RTT
00053 {
00054 using namespace std;
00055
00056 ParserScriptingAccess::ParserScriptingAccess( TaskContext* parent )
00057 : ScriptingAccess(parent), sproc(0)
00058 {
00059 OperationInterface* obj = parent->getObject("scripting");
00060 obj = this->createTaskObject( obj );
00061 parent->addObject( obj );
00062 }
00063
00064 bool ParserScriptingAccess::doExecute(const std::string& code)
00065 {
00066 return this->execute(code) >= 0;
00067 }
00068
00069 bool ParserScriptingAccess::doLoadPrograms( std::string filename )
00070 {
00071 return this->loadPrograms(filename, false);
00072 }
00073
00074 bool ParserScriptingAccess::doLoadProgramText( std::string code )
00075 {
00076 return this->loadPrograms(code, "string", false);
00077 }
00078 bool ParserScriptingAccess::doUnloadProgram( std::string name )
00079 {
00080 return this->unloadProgram(name, false);
00081 }
00082
00083 bool ParserScriptingAccess::doLoadStateMachines( std::string filename )
00084 {
00085 return this->loadStateMachines(filename, false);
00086 }
00087 bool ParserScriptingAccess::doLoadStateMachineText( std::string code )
00088 {
00089 return this->loadStateMachines(code, "string", false);
00090 }
00091 bool ParserScriptingAccess::doUnloadStateMachine( std::string name )
00092 {
00093 return this->unloadStateMachine(name, false);
00094 }
00095
00096 OperationInterface* ParserScriptingAccess::createTaskObject(OperationInterface* obj)
00097 {
00098 if ( !obj )
00099 obj = new TaskObject("scripting","Access to the Scripting interface. \
00100 Use this object in order to load or query programs or state machines.");
00101
00102 obj->methods()->addMethod( method( "execute", &ParserScriptingAccess::execute, this),
00103 "Execute a line of code.", "Code", "A single statement.");
00104
00105 obj->methods()->addMethod( method( "loadPrograms", &ParserScriptingAccess::doLoadPrograms, this),
00106 "Load a program from a given file.", "Filename", "The filename of the script." );
00107 obj->methods()->addMethod( method( "loadProgramText", &ParserScriptingAccess::doLoadProgramText, this),
00108 "Load a program from a string.", "Code", "A string containing one or more program scripts." );
00109 obj->methods()->addMethod( method( "unloadProgram", &ParserScriptingAccess::doUnloadProgram, this),
00110 "Remove a loaded program.", "Name", "The name of the loaded Program" );
00111
00112
00113 obj->methods()->addMethod( method( "getProgramStatus", &ParserScriptingAccess::getProgramStatus, this),
00114 "Get the status of a program?", "Name", "The Name of the loaded Program" );
00115 obj->methods()->addMethod( method( "getProgramLine", &ParserScriptingAccess::getProgramLine, this),
00116 "Get the current line of execution of a program?", "Name", "The Name of the loaded Program" );
00117
00118
00119 obj->methods()->addMethod( method( "loadStateMachines", &ParserScriptingAccess::doLoadStateMachines, this),
00120 "Load a state machine from a given file.", "Filename", "The filename of the script." );
00121 obj->methods()->addMethod( method( "loadStateMachineText", &ParserScriptingAccess::doLoadStateMachineText, this),
00122 "Load a state machine from a string.", "Code", "A string containing one or more state machine scripts." );
00123 obj->methods()->addMethod( method( "unloadStateMachine", &ParserScriptingAccess::doUnloadStateMachine, this),
00124 "Remove a loaded state machine.", "Name", "The name of the loaded State Machine" );
00125
00126
00127 obj->methods()->addMethod( method( "getStateMachineStatus", &ParserScriptingAccess::getStateMachineStatus, this),
00128 "Get the status of a state machine?", "Name", "The Name of the loaded State Machine" );
00129 obj->methods()->addMethod( method( "getStateMachineLine", &ParserScriptingAccess::getStateMachineLine, this),
00130 "Get the current line of execution of a state machine?", "Name", "The Name of the loaded State Machine" );
00131
00132 return obj;
00133 }
00134
00135 ParserScriptingAccess::~ParserScriptingAccess()
00136 {
00137 delete sproc;
00138 }
00139
00140 int ParserScriptingAccess::execute(const std::string& code ){
00141 if (sproc == 0)
00142 sproc = new StatementProcessor(mparent);
00143 return sproc->execute( code );
00144 }
00145
00146 DispatchInterface::shared_ptr ParserScriptingAccess::getCommand( int ticket ){
00147 if (sproc)
00148 return sproc->getCommand(ticket);
00149 return DispatchInterface::shared_ptr();
00150 }
00151
00152 ParserScriptingAccess::Functions ParserScriptingAccess::loadFunctions( std::string file, bool do_throw )
00153 {
00154 std::ifstream inputfile(file.c_str());
00155 if ( !inputfile ) {
00156 Logger::In in("ParserScriptingAccess::loadFunctions");
00157 Logger::log() << Logger::Error << "Script "+file+" does not exist." << Logger::endl;
00158 return Functions();
00159 }
00160 std::string text;
00161 inputfile.unsetf( std::ios_base::skipws );
00162 std::istream_iterator<char> streambegin( inputfile );
00163 std::istream_iterator<char> streamend;
00164 std::copy( streambegin, streamend, std::back_inserter( text ) );
00165 return this->loadFunctions( text, file, do_throw );
00166 }
00167
00168 ParserScriptingAccess::Functions ParserScriptingAccess::loadFunctions( string code, string filename, bool mrethrow )
00169 {
00170
00171 Logger::In in("ParserScriptingAccess::loadFunctions");
00172 Parser p;
00173 Functions exec;
00174 Functions ret;
00175 try {
00176 Logger::log() << Logger::Info << "Parsing file "<<filename << Logger::endl;
00177 ret = p.parseFunction(code, mparent, filename);
00178 }
00179 catch( const file_parse_exception& exc )
00180 {
00181 #ifndef ORO_EMBEDDED
00182 Logger::log() << Logger::Error << filename<<" :"<< exc.what() << Logger::endl;
00183 if ( mrethrow )
00184 throw;
00185 #endif
00186 return Functions();
00187 }
00188 if ( ret.empty() )
00189 {
00190 Logger::log() << Logger::Debug << "No Functions executed from "<< filename << Logger::endl;
00191 Logger::log() << Logger::Info << filename <<" : Successfully parsed." << Logger::endl;
00192 return Functions();
00193 } else {
00194
00195 for( Parser::ParsedFunctions::iterator it = ret.begin(); it != ret.end(); ++it) {
00196 Logger::log() << "Queueing Function "<< (*it)->getName() << Logger::endl;
00197 if ( mparent->engine()->programs()->runFunction( it->get() ) == false) {
00198 Logger::log() << Logger::Error << "Could not run Function '"<< (*it)->getName() <<"' :" << Logger::nl;
00199 Logger::log() << "Processor not accepting or function queue is full." << Logger::endl;
00200 } else
00201 exec.push_back( *it );
00202 }
00203 }
00204 return exec;
00205
00206 }
00207
00208 bool ParserScriptingAccess::loadPrograms( std::string file, bool do_throw )
00209 {
00210 std::ifstream inputfile(file.c_str());
00211 if ( !inputfile ) {
00212 Logger::In in("ParserScriptingAccess::loadProgram");
00213 Logger::log() << Logger::Error << "Script "+file+" does not exist." << Logger::endl;
00214 return false;
00215 }
00216 std::string text;
00217 inputfile.unsetf( std::ios_base::skipws );
00218 std::istream_iterator<char> streambegin( inputfile );
00219 std::istream_iterator<char> streamend;
00220 std::copy( streambegin, streamend, std::back_inserter( text ) );
00221 return this->loadPrograms( text, file, do_throw );
00222 }
00223
00224 bool ParserScriptingAccess::loadPrograms( string code, string filename, bool mrethrow ){
00225
00226 Logger::In in("ProgramLoader::loadProgram");
00227 Parser parser;
00228 Parser::ParsedPrograms pg_list;
00229 try {
00230 Logger::log() << Logger::Info << "Parsing file "<<filename << Logger::endl;
00231 pg_list = parser.parseProgram(code, mparent, filename );
00232 }
00233 catch( const file_parse_exception& exc )
00234 {
00235 #ifndef ORO_EMBEDDED
00236 Logger::log() << Logger::Error <<filename<<" :"<< exc.what() << Logger::endl;
00237 if ( mrethrow )
00238 throw;
00239 #endif
00240 return false;
00241 }
00242 if ( pg_list.empty() )
00243 {
00244 Logger::log() << Logger::Info << filename <<" : Successfully parsed." << Logger::endl;
00245 return true;
00246 } else {
00247
00248 bool error = false;
00249 string errors;
00250 for( Parser::ParsedPrograms::iterator it = pg_list.begin(); it != pg_list.end(); ++it) {
00251 try {
00252 Logger::log() << Logger::Info << "Loading Program '"<< (*it)->getName() <<"'" <<Logger::endl;
00253 if (mparent->engine()->programs()->loadProgram( *it ) == false)
00254 error = true;
00255 } catch (program_load_exception& e ) {
00256 Logger::log() << Logger::Error << "Could not load Program '"<< (*it)->getName() <<"' :" << Logger::nl;
00257 #ifndef ORO_EMBEDDED
00258 Logger::log() << e.what() << Logger::endl;
00259 if ( mrethrow )
00260 errors += "Could not load Program '"+ (*it)->getName() +"' :\n"+e.what()+'\n';
00261 #endif
00262 error = true;
00263 }
00264 }
00265 #ifndef ORO_EMBEDDED
00266 if (error && mrethrow )
00267 throw program_load_exception( errors );
00268 #endif
00269 return !error;
00270 }
00271
00272 }
00273
00274 bool ParserScriptingAccess::unloadProgram( string name, bool do_throw ){
00275 Logger::In in("ParserScriptingAccess::unloadProgram");
00276 try {
00277 Logger::log() << Logger::Info << "Unloading Program '"<< name <<"'"<< Logger::endl;
00278 if (mparent->engine()->programs()->unloadProgram(name) == false)
00279 return false;
00280 } catch (program_unload_exception& e ) {
00281 Logger::log() << Logger::Error << "Could not unload Program '"<< name <<"' :" << Logger::nl;
00282 #ifndef ORO_EMBEDDED
00283 Logger::log() << e.what() << Logger::endl;
00284 if ( do_throw )
00285 throw;
00286 #endif
00287 return false;
00288 }
00289 return true;
00290 }
00291
00292
00293 bool ParserScriptingAccess::loadStateMachines( std::string file, bool do_throw )
00294 {
00295 std::ifstream inputfile(file.c_str());
00296 if ( !inputfile ) {
00297 Logger::In in("ParserScriptingAccess::loadStateMachine");
00298 Logger::log() << Logger::Error << "Script "+file+" does not exist." << Logger::endl;
00299 return false;
00300 }
00301 std::string text;
00302 inputfile.unsetf( std::ios_base::skipws );
00303 std::istream_iterator<char> streambegin( inputfile );
00304 std::istream_iterator<char> streamend;
00305 std::copy( streambegin, streamend, std::back_inserter( text ) );
00306 return this->loadStateMachines( text, file, do_throw );
00307 }
00308
00309 bool ParserScriptingAccess::loadStateMachines( string code, string filename, bool mrethrow )
00310 {
00311 Logger::In in("ParserScriptingAccess::loadStateMachine");
00312 Parser parser;
00313 Parser::ParsedStateMachines pg_list;
00314 try {
00315 Logger::log() << Logger::Info << "Parsing file "<<filename << Logger::endl;
00316 pg_list = parser.parseStateMachine( code, mparent, filename );
00317 }
00318 catch( const file_parse_exception& exc )
00319 {
00320 #ifndef ORO_EMBEDDED
00321 Logger::log() << Logger::Error <<filename<<" :"<< exc.what() << Logger::endl;
00322 if ( mrethrow )
00323 throw;
00324 #endif
00325 return false;
00326 }
00327 if ( pg_list.empty() )
00328 {
00329 Logger::log() << Logger::Error << "No StateMachines instantiated in "<< filename << Logger::endl;
00330 return false;
00331 } else {
00332 bool error = false;
00333 string errors;
00334
00335 for( Parser::ParsedStateMachines::iterator it = pg_list.begin(); it != pg_list.end(); ++it) {
00336 try {
00337 Logger::log() << Logger::Info << "Loading StateMachine '"<< (*it)->getName()<<"'" << Logger::endl;
00338 if (mparent->engine()->states()->loadStateMachine( *it ) == false)
00339 return false;
00340 } catch (program_load_exception& e ) {
00341 Logger::log() << Logger::Error << "Could not load StateMachine '"<< (*it)->getName()<<"' :" << Logger::nl;
00342 #ifndef ORO_EMBEDDED
00343 Logger::log() << e.what() << Logger::endl;
00344 if ( mrethrow )
00345 errors += "Could not load Program '"+ (*it)->getName() +"' :\n"+e.what()+'\n';
00346 #endif
00347 error = true;
00348 }
00349 }
00350 #ifndef ORO_EMBEDDED
00351 if ( error && mrethrow )
00352 throw program_load_exception( errors );
00353 #endif
00354 return !error;
00355 }
00356
00357 return false;
00358 }
00359
00360 bool ParserScriptingAccess::unloadStateMachine( string name, bool do_throw ) {
00361 Logger::In in("ParserScriptingAccess::unloadStateMachine");
00362 try {
00363 Logger::log() << Logger::Info << "Unloading StateMachine '"<< name <<"'"<< Logger::endl;
00364 if (mparent->engine()->states()->unloadStateMachine(name) == false)
00365 return false;
00366 } catch (program_unload_exception& e ) {
00367 Logger::log() << Logger::Error << "Could not unload StateMachine '"<< name <<"' :" << Logger::nl;
00368 #ifndef ORO_EMBEDDED
00369 Logger::log() << e.what() << Logger::endl;
00370 if ( do_throw )
00371 throw;
00372 #endif
00373 return false;
00374 }
00375 return true;
00376 }
00377
00378 }