Orocos Real-Time Toolkit  2.8.3
StatementProcessor.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  tag: Peter Soetens Mon Jun 26 13:25:57 CEST 2006 StatementProcessor.cxx
3 
4  StatementProcessor.cxx - description
5  -------------------
6  begin : Mon June 26 2006
7  copyright : (C) 2006 Peter Soetens
8  email : peter.soetens@fmtc.be
9 
10  ***************************************************************************
11  * This library is free software; you can redistribute it and/or *
12  * modify it under the terms of the GNU General Public *
13  * License as published by the Free Software Foundation; *
14  * version 2 of the License. *
15  * *
16  * As a special exception, you may use this file as part of a free *
17  * software library without restriction. Specifically, if other files *
18  * instantiate templates or use macros or inline functions from this *
19  * file, or you compile this file and link it with other files to *
20  * produce an executable, this file does not by itself cause the *
21  * resulting executable to be covered by the GNU General Public *
22  * License. This exception does not however invalidate any other *
23  * reasons why the executable file might be covered by the GNU General *
24  * Public License. *
25  * *
26  * This library is distributed in the hope that it will be useful, *
27  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
28  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
29  * Lesser General Public License for more details. *
30  * *
31  * You should have received a copy of the GNU General Public *
32  * License along with this library; if not, write to the Free Software *
33  * Foundation, Inc., 59 Temple Place, *
34  * Suite 330, Boston, MA 02111-1307 USA *
35  * *
36  ***************************************************************************/
37 
38 
39 
40 #include "StatementProcessor.hpp"
41 #include "Parser.hpp"
42 #include "parse_exception.hpp"
43 
44 #include "../TaskContext.hpp"
45 #include "../types/TypeStream.hpp"
46 #include "../Logger.hpp"
47 
48 #include <vector>
49 #include <boost/tuple/tuple.hpp>
50 #include <iostream>
51 
52 
53 using namespace boost;
54 
55 namespace RTT
56 { namespace scripting {
57 
58  using namespace detail;
60  {
61  public:
63  D() {}
64 
65  void printResult( DataSourceBase* ds, bool recurse) {
66  std::string prompt(" = ");
67  // setup prompt :
68  Logger::log() << Logger::Info <<prompt;
69  doPrint( ds, recurse );
70  Logger::log() << Logger::endl;
71  }
72 
73  void doPrint( DataSourceBase* ds, bool recurse) {
74  // this is needed for ds's that rely on initialision.
75  // e.g. eval true once or time measurements.
76  // becomes only really handy for 'watches' (todo).
77  ds->reset();
82  // this method can print some primitive DataSource<>'s.
84  if (dsb) {
85  Logger::log() << dsb->get();
86  return;
87  }
89  if (dsi) {
90  Logger::log() << dsi->get() ;
91  return;
92  }
93 #if 0
94  // does not work yet with CORBA layer.
96  if (dsl) {
97  Logger::log() << dsl->get() ;
98  return;
99  }
100 #endif
102  if (dsui) {
103  Logger::log() << dsui->get() ;
104  return;
105  }
107  if (dss) {
108  Logger::log() <<'"'<< dss->get() << '"' ;
109  return;
110  }
111 #if 0
113  if (dsvval) {
114  Logger::log() << dsvval->get() ;
115  return;
116  }
118  if (ds6d) {
119  Logger::log() << ds6d->get() ;
120  return;
121  }
122 #endif
124  if (dsd) {
125  Logger::log() << dsd->get() ;
126  return;
127  }
129  if (dsc) {
130  Logger::log() <<'\''<< dsc->get()<<'\'' ;
131  return;
132  }
133 
135  if (dspbag) {
136  PropertyBag bag( dspbag->get() );
137  if (!recurse) {
138  int siz = bag.getProperties().size();
139  Logger::log() << siz <<" Properties";
140  } else {
141  if ( ! bag.empty() ) {
142  Logger::log() <<Logger::nl;
143  for( PropertyBag::iterator it= bag.getProperties().begin(); it!=bag.getProperties().end(); ++it) {
144  Logger::log() <<(*it)->getType()<<" "<< (*it)->getName();
145  DataSourceBase::shared_ptr propds = (*it)->getDataSource();
146  this->printResult( propds.get(), false );
147  Logger::log() <<" ("<<(*it)->getDescription()<<')' << Logger::nl;
148  }
149  } else {
150  Logger::log() <<"(empty PropertyBag)";
151  }
152  }
153  return;
154  }
155 
156  // Leave void as last since any DS is convertible to void !
158  if (dsvd) {
159  dsvd->get();
160  Logger::log() << "(void)" ;
161  return;
162  }
163 
164  if (ds) {
165  ds->evaluate();
166  Logger::log() << "( result type '"+ds->getType()+"' not known to TaskBrowser )" ;
167  }
168 
169  }
170 
171  };
172 
173 
174  StatementProcessor::StatementProcessor(TaskContext* tc)
175  : d ( new D() )
176  {
177  d->tc = tc;
178  }
179 
181  delete d;
182  }
183 
184  int StatementProcessor::execute(const std::string& comm)
185  {
186  Logger::In in("StatementProcessor");
187  TaskContext* taskcontext = d->tc;
188 
189  // Minor hack : also check if it was an attribute of current TC, for example,
190  // if both the object and attribute with that name exist. the if
191  // statement after this one would return and not give the expr parser
192  // time to evaluate 'comm'.
193  if ( taskcontext->provides()->getValue( comm ) ) {
194  d->printResult( taskcontext->provides()->getValue( comm )->getDataSource().get(), true );
195  return 0;
196  }
197 
198  Parser _parser;
199 
200  Logger::log() <<Logger::Debug << "Trying ValueChange...";
201  try {
202  // Check if it was a method or datasource :
203  DataSourceBase::shared_ptr ds = _parser.parseValueChange( comm, taskcontext );
204  // methods and DS'es are processed immediately.
205  if ( ds.get() != 0 ) {
206  Logger::log() << "ok" << Logger::endl;
207  d->printResult( ds.get(), false );
208  return 0; // done here
209  } else
211  } catch ( fatal_semantic_parse_exception& pe ) { // incorr args, ...
212  // way to fatal, must be reported immediately
213  Logger::log() << Logger::Debug << "fatal_semantic_parse_exception: ";
214  Logger::log() << Logger::Error << pe.what() <<Logger::nl;
215  return -1;
216  } catch ( syntactic_parse_exception& pe ) { // wrong content after = sign etc..
217  // syntactic errors must be reported immediately
218  Logger::log() << Logger::Error << "syntactic_parse_exception: ";
219  Logger::log() << Logger::Error << pe.what() <<Logger::nl;
220  return -1;
221  } catch ( parse_exception_parser_fail &pe )
222  {
223  // ignore, try next parser
224  Logger::log() << Logger::Debug << "Ignoring ValueChange exception :"<<Logger::nl;
225  Logger::log() << Logger::Debug << pe.what() <<Logger::nl;
226  } catch ( parse_exception& pe ) {
227  // syntactic errors must be reported immediately
228  Logger::log() << Logger::Error << "parse_exception :";
229  Logger::log() << Logger::Error << pe.what() <<Logger::nl;
230  return -1;
231  }
232  Logger::log() << Logger::Debug << "Trying Expression..."<<Logger::nl;
233  try {
234  // Check if it was a method or datasource :
235  DataSourceBase::shared_ptr ds = _parser.parseExpression( comm, taskcontext );
236  // methods and DS'es are processed immediately.
237  if ( ds.get() != 0 ) {
238  d->printResult( ds.get(), true );
239  return 0; // done here
240  } else
241  Logger::log() << Logger::Error << "returned zero !"<<Logger::nl;
242  } catch ( syntactic_parse_exception& pe ) { // missing brace etc
243  // syntactic errors must be reported immediately
244  Logger::log() << Logger::Error << "syntactic_parse_exception :";
245  Logger::log() << Logger::Error << pe.what() <<Logger::nl;
246  return -1;
247  } catch ( fatal_semantic_parse_exception& pe ) { // incorr args, ...
248  // way to fatal, must be reported immediately
249  Logger::log() << Logger::Error << "fatal_semantic_parse_exception :";
250  Logger::log() << Logger::Error << pe.what() <<Logger::nl;
251  return -1;
252  } catch ( parse_exception_parser_fail &pe ) {
253  // ignore, try next parser
254  Logger::log() << Logger::Debug << "Ignoring Expression exception :"<<Logger::nl;
255  Logger::log() << Logger::Debug << pe.what() <<Logger::nl;
256  } catch ( parse_exception& pe ) {
257  // ignore, try next parser
258  Logger::log() << Logger::Debug << "Ignoring Expression parse_exception :"<<Logger::nl;
259  Logger::log() << Logger::Debug << pe.what() <<Logger::nl;
260  }
261  return -1;
262  }
263 
264 }}
265 
virtual std::string getType() const =0
Return useful type info in a human readable format.
virtual result_t get() const =0
Return the data as type T.
Service::shared_ptr provides()
Returns this Service.
virtual const std::string what() const =0
void printResult(DataSourceBase *ds, bool recurse)
The base class for all internal data representations.
static std::ostream & nl(std::ostream &__os)
Insert a newline &#39; &#39; in the ostream.
Definition: Logger.cpp:373
void doPrint(DataSourceBase *ds, bool recurse)
A container for holding references to properties.
Definition: PropertyBag.hpp:96
virtual void reset()
Reset the data to initial values.
Definition: DataSource.cpp:87
basic_ostreams & endl(basic_ostreams &s)
Flush and newline.
Definition: rtstreams.cpp:110
virtual bool evaluate() const =0
Force an evaluation of the DataSourceBase.
static std::ostream & endl(std::ostream &__os)
Definition: Logger.cpp:383
This is the uppermost exception class in the parser system.
This class is the public interface to the Orocos Program Parser Framework.
Definition: Parser.hpp:65
Properties & getProperties()
Returns a list of all the property objects in this bag.
A normal syntactic parse exception means the parser recognised the input, but got stuck later due to ...
base::DataSourceBase::shared_ptr parseExpression(const std::string &s, TaskContext *)
Parses the expression in s.
Definition: Parser.cpp:160
Notify the Logger in which &#39;module&#39; the message occured.
Definition: Logger.hpp:159
An exception which a parser may throw to indicate that it failed to understand the input...
static Logger & log()
As Instance(), but more userfriendly.
Definition: Logger.cpp:117
The TaskContext is the C++ representation of an Orocos component.
Definition: TaskContext.hpp:93
Properties::iterator iterator
An iterator over the Properties.
boost::intrusive_ptr< DataSourceBase > shared_ptr
Use this type to store a pointer to a DataSourceBase.
Contains TaskContext, Activity, OperationCaller, Operation, Property, InputPort, OutputPort, Attribute.
Definition: Activity.cpp:51
int execute(const std::string &code)
Execute a script statement.
A Fatal Semantic parse exception means the parser knows that the parsing failed dramatically and shou...
base::DataSourceBase::shared_ptr parseValueChange(const std::string &s, TaskContext *)
Parses a change of a value in s.
Definition: Parser.cpp:191