Orocos Real-Time Toolkit  2.9.0
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 {
57  using namespace detail;
59  {
60  public:
62  D() {}
63 
64  void printResult( DataSourceBase* ds, bool recurse) {
65  std::string prompt(" = ");
66  // setup prompt :
67  Logger::log() << Logger::Info <<prompt;
68  doPrint( ds, recurse );
69  Logger::log() << Logger::endl;
70  }
71 
72  void doPrint( DataSourceBase* ds, bool recurse) {
73  // this is needed for ds's that rely on initialision.
74  // e.g. eval true once or time measurements.
75  // becomes only really handy for 'watches' (todo).
76  ds->reset();
81  // this method can print some primitive DataSource<>'s.
83  if (dsb) {
84  Logger::log() << dsb->get();
85  return;
86  }
88  if (dsi) {
89  Logger::log() << dsi->get() ;
90  return;
91  }
92 #if 0
93  // does not work yet with CORBA layer.
95  if (dsl) {
96  Logger::log() << dsl->get() ;
97  return;
98  }
99 #endif
101  if (dsui) {
102  Logger::log() << dsui->get() ;
103  return;
104  }
106  if (dss) {
107  Logger::log() <<'"'<< dss->get() << '"' ;
108  return;
109  }
110 #if 0
112  if (dsvval) {
113  Logger::log() << dsvval->get() ;
114  return;
115  }
117  if (ds6d) {
118  Logger::log() << ds6d->get() ;
119  return;
120  }
121 #endif
123  if (dsd) {
124  Logger::log() << dsd->get() ;
125  return;
126  }
128  if (dsc) {
129  Logger::log() <<'\''<< dsc->get()<<'\'' ;
130  return;
131  }
132 
134  if (dspbag) {
135  PropertyBag bag( dspbag->get() );
136  if (!recurse) {
137  int siz = bag.getProperties().size();
138  Logger::log() << siz <<" Properties";
139  } else {
140  if ( ! bag.empty() ) {
141  Logger::log() <<Logger::nl;
142  for( PropertyBag::iterator it= bag.getProperties().begin(); it!=bag.getProperties().end(); ++it) {
143  Logger::log() <<(*it)->getType()<<" "<< (*it)->getName();
144  DataSourceBase::shared_ptr propds = (*it)->getDataSource();
145  this->printResult( propds.get(), false );
146  Logger::log() <<" ("<<(*it)->getDescription()<<')' << Logger::nl;
147  }
148  } else {
149  Logger::log() <<"(empty PropertyBag)";
150  }
151  }
152  return;
153  }
154 
155  // Leave void as last since any DS is convertible to void !
157  if (dsvd) {
158  dsvd->get();
159  Logger::log() << "(void)" ;
160  return;
161  }
162 
163  if (ds) {
164  ds->evaluate();
165  Logger::log() << "( result type '"+ds->getType()+"' not known to TaskBrowser )" ;
166  }
167 
168  }
169 
170  };
171 
172 
173  StatementProcessor::StatementProcessor(TaskContext* tc)
174  : d ( new D() )
175  {
176  d->tc = tc;
177  }
178 
179  StatementProcessor::~StatementProcessor() {
180  delete d;
181  }
182 
183  int StatementProcessor::execute(const std::string& comm)
184  {
185  Logger::In in("StatementProcessor");
186  TaskContext* taskcontext = d->tc;
187 
188  // Minor hack : also check if it was an attribute of current TC, for example,
189  // if both the object and attribute with that name exist. the if
190  // statement after this one would return and not give the expr parser
191  // time to evaluate 'comm'.
192  if ( taskcontext->provides()->getValue( comm ) ) {
193  d->printResult( taskcontext->provides()->getValue( comm )->getDataSource().get(), true );
194  return 0;
195  }
196 
197  Parser _parser;
198 
199  Logger::log() <<Logger::Debug << "Trying ValueChange...";
200  try {
201  // Check if it was a method or datasource :
202  DataSourceBase::shared_ptr ds = _parser.parseValueChange( comm, taskcontext );
203  // methods and DS'es are processed immediately.
204  if ( ds.get() != 0 ) {
205  Logger::log() << "ok" << Logger::endl;
206  d->printResult( ds.get(), false );
207  return 0; // done here
208  } else
209  Logger::log() <<Logger::Debug << "no"<<Logger::endl;
210  } catch ( fatal_semantic_parse_exception& pe ) { // incorr args, ...
211  // way to fatal, must be reported immediately
212  Logger::log() << Logger::Debug << "fatal_semantic_parse_exception: ";
213  Logger::log() << Logger::Error << pe.what() <<Logger::nl;
214  return -1;
215  } catch ( syntactic_parse_exception& pe ) { // wrong content after = sign etc..
216  // syntactic errors must be reported immediately
217  Logger::log() << Logger::Error << "syntactic_parse_exception: ";
218  Logger::log() << Logger::Error << pe.what() <<Logger::nl;
219  return -1;
220  } catch ( parse_exception_parser_fail &pe )
221  {
222  // ignore, try next parser
223  Logger::log() << Logger::Debug << "Ignoring ValueChange exception :"<<Logger::nl;
224  Logger::log() << Logger::Debug << pe.what() <<Logger::nl;
225  } catch ( parse_exception& pe ) {
226  // syntactic errors must be reported immediately
227  Logger::log() << Logger::Error << "parse_exception :";
228  Logger::log() << Logger::Error << pe.what() <<Logger::nl;
229  return -1;
230  }
231  Logger::log() << Logger::Debug << "Trying Expression..."<<Logger::nl;
232  try {
233  // Check if it was a method or datasource :
234  DataSourceBase::shared_ptr ds = _parser.parseExpression( comm, taskcontext );
235  // methods and DS'es are processed immediately.
236  if ( ds.get() != 0 ) {
237  d->printResult( ds.get(), true );
238  return 0; // done here
239  } else
240  Logger::log() << Logger::Error << "returned zero !"<<Logger::nl;
241  } catch ( syntactic_parse_exception& pe ) { // missing brace etc
242  // syntactic errors must be reported immediately
243  Logger::log() << Logger::Error << "syntactic_parse_exception :";
244  Logger::log() << Logger::Error << pe.what() <<Logger::nl;
245  return -1;
246  } catch ( fatal_semantic_parse_exception& pe ) { // incorr args, ...
247  // way to fatal, must be reported immediately
248  Logger::log() << Logger::Error << "fatal_semantic_parse_exception :";
249  Logger::log() << Logger::Error << pe.what() <<Logger::nl;
250  return -1;
251  } catch ( parse_exception_parser_fail &pe ) {
252  // ignore, try next parser
253  Logger::log() << Logger::Debug << "Ignoring Expression exception :"<<Logger::nl;
254  Logger::log() << Logger::Debug << pe.what() <<Logger::nl;
255  } catch ( parse_exception& pe ) {
256  // ignore, try next parser
257  Logger::log() << Logger::Debug << "Ignoring Expression parse_exception :"<<Logger::nl;
258  Logger::log() << Logger::Debug << pe.what() <<Logger::nl;
259  }
260  return -1;
261  }
262 
263 }
264 
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
The base class for all internal data representations.
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.
void doPrint(DataSourceBase *ds, bool recurse)
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.
void printResult(DataSourceBase *ds, bool recurse)
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...
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:52
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