ParserScriptingAccess.cpp

00001 /***************************************************************************
00002   tag: Peter Soetens  Mon Jun 26 13:25:57 CEST 2006  ParserScriptingAccess.cxx 
00003 
00004                         ParserScriptingAccess.cxx -  description
00005                            -------------------
00006     begin                : Mon June 26 2006
00007     copyright            : (C) 2006 Peter Soetens
00008     email                : peter.soetens@fmtc.be
00009  
00010  ***************************************************************************
00011  *   This library is free software; you can redistribute it and/or         *
00012  *   modify it under the terms of the GNU General Public                   *
00013  *   License as published by the Free Software Foundation;                 *
00014  *   version 2 of the License.                                             *
00015  *                                                                         *
00016  *   As a special exception, you may use this file as part of a free       *
00017  *   software library without restriction.  Specifically, if other files   *
00018  *   instantiate templates or use macros or inline functions from this     *
00019  *   file, or you compile this file and link it with other files to        *
00020  *   produce an executable, this file does not by itself cause the         *
00021  *   resulting executable to be covered by the GNU General Public          *
00022  *   License.  This exception does not however invalidate any other        *
00023  *   reasons why the executable file might be covered by the GNU General   *
00024  *   Public License.                                                       *
00025  *                                                                         *
00026  *   This library is distributed in the hope that it will be useful,       *
00027  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00028  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
00029  *   Lesser General Public License for more details.                       *
00030  *                                                                         *
00031  *   You should have received a copy of the GNU General Public             *
00032  *   License along with this library; if not, write to the Free Software   *
00033  *   Foundation, Inc., 59 Temple Place,                                    *
00034  *   Suite 330, Boston, MA  02111-1307  USA                                *
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         // Methods for loading programs
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         // Query Methods for programs
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         // Methods for loading state machines
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         // Query Methods for state machines
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/* = false*/ )
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               // Load all listed functions in the TaskContext's Processor:
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 ); // is being executed.
00202               }
00203           }
00204       return exec;
00205 
00206     }
00207     
00208     bool ParserScriptingAccess::loadPrograms( std::string file, bool do_throw /*= false*/ )
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               // Load all listed programs in the TaskContext's Processor:
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       // never reached
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 /*= false*/  )
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                 // Load all listed stateMachines in the TaskContext's Processor:
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         // never reached
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 }

Generated on Tue Mar 25 17:41:49 2008 for OrocosReal-TimeToolkit by  doxygen 1.5.3