OpenASIP  2.0
OperationIndex.cc
Go to the documentation of this file.
1 /*
2  Copyright (c) 2002-2015 Tampere University.
3 
4  This file is part of TTA-Based Codesign Environment (TCE).
5 
6  Permission is hereby granted, free of charge, to any person obtaining a
7  copy of this software and associated documentation files (the "Software"),
8  to deal in the Software without restriction, including without limitation
9  the rights to use, copy, modify, merge, publish, distribute, sublicense,
10  and/or sell copies of the Software, and to permit persons to whom the
11  Software is furnished to do so, subject to the following conditions:
12 
13  The above copyright notice and this permission notice shall be included in
14  all copies or substantial portions of the Software.
15 
16  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22  DEALINGS IN THE SOFTWARE.
23  */
24 /**
25  * @file OperationIndex.cc
26  *
27  * Definition of OperationIndex class.
28  *
29  * @author Jussi Nykänen 2004 (nykanen-no.spam-cs.tut.fi)
30  * @author Pekka Jääskeläinen 2015
31  * @note rating: yellow
32  * @note reviewed 19 August 2004 by pj, jn, ao, ac
33  */
34 
35 #include "OperationIndex.hh"
36 #include "Operation.hh"
37 #include "OperationModule.hh"
38 #include "ObjectState.hh"
39 #include "FileSystem.hh"
40 #include "Application.hh"
41 #include "AssocTools.hh"
42 #include "StringTools.hh"
43 #include "SequenceTools.hh"
44 #include "MapTools.hh"
45 #include "OperationBuilder.hh"
48 
49 using std::map;
50 using std::string;
51 using std::vector;
52 
53 const string OperationIndex::PROPERTY_FILE_EXTENSION = ".opp";
54 
55 /**
56  * Constructor.
57  */
58 OperationIndex::OperationIndex() : loader_(*this) {
59 }
60 
61 /**
62  * Destructor.
63  *
64  * Deletes all object state trees modeling module properties. Deletes all
65  * modules.
66  */
71 }
72 
73 /**
74  * Adds a path to search path list.
75  *
76  * When the path is added, all modules in that path are automatically scanned
77  * and recorded.
78  *
79  * @param path The path to be added.
80  */
81 void
82 OperationIndex::addPath(const std::string& path) {
83 
84  ModuleTable::iterator iter = modulesInPath_.find(path);
85  if (iter != modulesInPath_.end()) {
86  return;
87  }
88 
89  paths_.push_back(path);
90  vector<string> modules;
91  string pattern = path + FileSystem::DIRECTORY_SEPARATOR +
93 
94  FileSystem::globPath(pattern, modules);
95 
96  vector<OperationModule*> opModules;
97  for (unsigned int i = 0; i < modules.size(); i++) {
98  string file = FileSystem::fileOfPath(modules[i]);
99  string behaviourFile = modules[i];
100  string behaviourSourceFile =
101  behaviourFile.substr(0, behaviourFile.length() - 3) + "cc";
102 
103  // behaviour is .opb , change last letter from p to b
104  *(behaviourFile.rbegin()) = 'b';
105 
106  // load only modules which have behaviour file.
107  if (!FileSystem::fileExists(behaviourFile) &&
108  FileSystem::fileExists(behaviourSourceFile)) {
110  std::vector<std::string> output;
111  bool buildOk = opBuilder.buildObject(
112  file.substr(0, file.length()-4), behaviourSourceFile,
113  path, output);
114  if (!buildOk || !FileSystem::fileExists(behaviourFile)) {
115  std::cerr << "Warning: Found operation module specification "
116  << "file " << modules[i] << " and operation "
117  << "behavious source file " << behaviourSourceFile
118  << " without compiled behaviour "
119  << "implementation file "
120  << behaviourFile << "." << std::endl;
121  std::cerr << "Tried to compile behaviour impelementaton "
122  << "file, but the compilation failed to error: "
123  << std::endl;
124  for (unsigned int j = 0; j < output.size(); j++) {
125  std::cerr << output[j] << std::endl;
126  }
127  std::cerr << "This may cause program to hang if operation "
128  << "in this module is attempted to be simulated."
129  << std::endl;
130  }
131  }
134  modules_.push_back(module);
135  opModules.push_back(module);
136  }
137  modulesInPath_[path] = opModules;
138 }
139 
140 /**
141  * Returns the module by the given index in a given path.
142  *
143  * @param i The index of wanted module.
144  * @param path The path of the module
145  * @return The module by the given index in a given path, or null module if
146  * path is not found.
147  * @exception OutOfRange If index i is out of range.
148  * @exception PathNotFound If path is not found.
149  */
151 OperationIndex::module(int i, const std::string& path) {
152  ModuleTable::iterator it = modulesInPath_.find(path);
153  if (it == modulesInPath_.end()) {
154  string msg = "Path for the module not found.";
155  throw PathNotFound(__FILE__, __LINE__, __func__, msg, path);
156  }
157 
158  if (i < 0 || i > static_cast<int>((*it).second.size()) - 1) {
159  string msg = "Index out of range.";
160  throw OutOfRange(__FILE__, __LINE__, __func__, msg);
161  }
162 
163  OperationModule* module = ((*it).second)[i];
164  return *module;
165 }
166 
167 /**
168  * Returns the number of modules in a path.
169  *
170  * @param path The path of the modules.
171  * @return The number of modules in a path.
172  * @exception PathNotFound If path is not found.
173  */
174 int
175 OperationIndex::moduleCount(const std::string& path) const {
176  ModuleTable::const_iterator it =
177  modulesInPath_.find(path);
178  if (it == modulesInPath_.end()) {
179  string msg = "Path for the modules not found.";
180  throw PathNotFound(__FILE__, __LINE__, __func__, msg, path);
181  }
182  return (*it).second.size();
183 }
184 
185 /**
186  * Adds a new module to OperationIndex.
187  *
188  * @param module Module to be added.
189  * @param path Path in which module is located.
190  * @exception PathNotFound If path is not found.
191  */
192 void
193 OperationIndex::addModule(OperationModule* module, const std::string& path) {
194  ModuleTable::iterator it = modulesInPath_.find(path);
195  if (it == modulesInPath_.end()) {
196  string method = "OperationIndex::addModule()";
197  string msg = "Path not found.";
198  throw PathNotFound(__FILE__, __LINE__, method, msg, path);
199  }
200  modules_.push_back(module);
201  (*it).second.push_back(module);
202 }
203 
204 /**
205  * Removes the module in a given path.
206  *
207  * @param path The name of the path.
208  * @param modName The name of the module.
209  * @exception PathNotFound If path is not found.
210  */
211 void
213  const std::string& path, const std::string& modName) {
214  ModuleTable::iterator iter = modulesInPath_.find(path);
215  if (iter == modulesInPath_.end()) {
216  string msg = "Paths of the module not found.";
217  throw PathNotFound(__FILE__, __LINE__, __func__, msg, path);
218  }
219 
220  OperationModule* toBeErased = NULL;
221 
222  vector<OperationModule*>::iterator modIter = (*iter).second.begin();
223  while (modIter != (*iter).second.end()) {
224  if ((*modIter)->name() == modName) {
225  toBeErased = *modIter;
226  (*iter).second.erase(modIter);
227  break;
228  }
229  modIter++;
230  }
231 
232  if (toBeErased == NULL) {
233  throw InstanceNotFound(
234  __FILE__, __LINE__, __func__,
235  "Operation module " + path + ":" + modName + " not found.");
236  }
237 
238  modIter = modules_.begin();
239  while (modIter != modules_.end()) {
240  if (*modIter == toBeErased) {
241  modules_.erase(modIter);
242  break;
243  }
244  modIter++;
245  }
246 
247  // erase module from DefinitionTable
248  DefinitionTable::iterator dIter = opDefinitions_.begin();
249  while (dIter != opDefinitions_.end()) {
250  if ((*dIter).first == toBeErased->propertiesModule()) {
251  opDefinitions_.erase(dIter);
252  delete (*dIter).second;
253  break;
254  }
255  dIter++;
256  }
257 
258  delete toBeErased;
259 }
260 
261 /**
262  * Refreshes module (usually when new operation is added to it).
263  *
264  * Refreshing is done by erasing the ObjectState tree of the module. That
265  * way it has to be read again.
266  *
267  * @param path The name of the path.
268  * @param modName The name of the module.
269  * @exception PathNotFound If path is not found.
270  */
271 void
273  const std::string& path, const std::string& modName) {
274  ModuleTable::iterator modIter = modulesInPath_.find(path);
275  if (modIter == modulesInPath_.end()) {
276  string msg = "Path for the module not found.";
277  throw PathNotFound(__FILE__, __LINE__, __func__, msg, path);
278  }
279 
280  vector<OperationModule*>::iterator iter = (*modIter).second.begin();
281  OperationModule* module = NULL;
282  while (iter != (*modIter).second.end()) {
283  if ((*iter)->name() == modName) {
284  module = (*iter);
285  break;
286  }
287  iter++;
288  }
289 
290  if (module == NULL) {
291  throw InstanceNotFound(
292  __FILE__, __LINE__, __func__,
293  "Operation module " + path + ":" + modName + " not found.");
294  }
295 
296  DefinitionTable::iterator it =
298  if (it == opDefinitions_.end()) {
299  return;
300  } else {
301  delete (*it).second;
302  opDefinitions_.erase(it);
303  }
304 }
305 
306 /**
307  * Returns the module in which a given operation is defined.
308  *
309  * If operation module is not found, a null operation module is returned.
310  *
311  * @param name The name of the operation.
312  * @return The OperationModule in which operation is defined.
313  */
315 OperationIndex::moduleOf(const std::string& name) {
316 
317  // let's iterate through every module to search an operation
318  for (unsigned int i = 0; i < paths_.size(); i++) {
319  OperationModule& module = moduleOf(paths_[i], name);
321  return module;
322  }
323  }
325 }
326 
327 /**
328  * Returns the name of the operation by the given index in a given module.
329  *
330  * @param i The index of the operation.
331  * @param om The OperationModule.
332  * @return The name of the operation by the given index in a given module.
333  * @exception OutOfRange If index i is out of range.
334  * @exception BadOperationModule When module is invalid.
335  */
336 string
338  DefinitionTable::iterator it = opDefinitions_.find(om.propertiesModule());
339  if (it == opDefinitions_.end()) {
340  try {
341  readOperations(om);
342  it = opDefinitions_.find(om.propertiesModule());
343  } catch (const SerializerException& s) {
344  brokenModules_.insert(&om);
345  string msg = "Error when reading module: " + s.errorMessage();
346  throw BadOperationModule(__FILE__, __LINE__, __func__, msg);
347  }
348  }
349 
350  ObjectState* op = (*it).second;
351  ObjectState* child = op->child(i);
352  return child->stringAttribute(Operation::OPRN_NAME);
353 }
354 
355 /**
356  * Returns the number of operations in a particular module.
357  *
358  * @param om The OperationModule.
359  * @return The number of operations in a module.
360  * @exception BadOperationModule When module is invalid.
361  */
362 int
364  DefinitionTable::iterator it = opDefinitions_.find(om.propertiesModule());
365  if (it == opDefinitions_.end()) {
366  try {
367  readOperations(om);
368  it = opDefinitions_.find(om.propertiesModule());
369  } catch (const SerializerException& s) {
370  brokenModules_.insert(&om);
371  string msg = "Error when reading module: " + s.errorMessage();
372  throw BadOperationModule(__FILE__, __LINE__, __func__, msg);
373  }
374  }
375  ObjectState* op = (*it).second;
376  return op->childCount();
377 }
378 
379 /**
380  * Read all operation definitions of a module.
381  *
382  * @param module The operation module to be read operations from.
383  * @exception SerializerException If reading fails.
384  */
385 void
390 }
391 
392 /**
393  * Searches for a module in which a given operation is defined all in a
394  * given path.
395  *
396  * If no module is found, NullOperationModule is returned.
397  *
398  * @param path The name of the path.
399  * @param operName The name of the operation.
400  * @return The module in which operation is defined or NullOperationModule.
401  */
404  const std::string& path,
405  const std::string& operName) {
406 
407  ModuleTable::const_iterator mt = modulesInPath_.find(path);
408  if (mt == modulesInPath_.end()) {
410  }
411 
412  vector<OperationModule*> mods = (*mt).second;
413 
414  // let's iterate through all modules in this path
415  for (unsigned int j = 0; j < mods.size(); j++) {
416 
417  if (brokenModules_.count(mods[j]))
418  continue;
419  DefinitionTable::const_iterator dt =
420  opDefinitions_.find(mods[j]->propertiesModule());
421  if (dt == opDefinitions_.end()) {
422 
423  // operations for this module are not yet read from XML file
424  // let's read them now
425  try {
426  readOperations(*mods[j]);
427  dt = opDefinitions_.find(mods[j]->propertiesModule());
428  } catch (const SerializerException& s) {
429  brokenModules_.insert(mods[j]);
430  // error occurred in reading, let's keep searching
431  continue;
432  }
433  }
434 
435  // let's go through all operations and try to find a specific
436  // one
437  ObjectState* op = (*dt).second;
438  for (int i = 0; i < op->childCount(); i++) {
439  ObjectState* child = op->child(i);
440  TCEString childName = child->stringAttribute(Operation::OPRN_NAME);
441  if (childName.ciEqual(operName)) {
442  return *(mods[j]);
443  }
444  }
445  }
447 }
448 
449 /**
450  * Returns a new instance of the Operation with the given
451  * name that is 'effective' based on the search path priorities.
452  */
453 Operation*
455 
456  OperationModule& mod = moduleOf(name);
457 
458  DefinitionTable::const_iterator dt =
459  opDefinitions_.find(mod.propertiesModule());
460 
461  assert (dt != opDefinitions_.end());
462 
463  ObjectState* root = (*dt).second;
464  ObjectState* child = NULL;
465 
466  // load operations
467  for (int i = 0; i < root->childCount(); i++) {
468  child = root->child(i);
469  const TCEString operName =
471 
472  /* Do not load all operations in the module because the user
473  might have overridden some of the operation (properties)
474  in a local search path with higher order. Just load the one
475  requested. */
476  if (!operName.ciEqual(name))
477  continue;
478 
479  Operation* oper =
481 
482  oper->loadState(child);
483  // add the behavior loader proxy
484  OperationBehaviorProxy* proxy =
485  new OperationBehaviorProxy(*oper, loader_);
486  proxies_.push_back(proxy);
487  oper->setBehavior(*proxy);
488  return oper;
489  }
490  return NULL;
491 }
OperationBehaviorProxy.hh
OperationIndex::addPath
void addPath(const std::string &path)
Definition: OperationIndex.cc:82
OperationIndex::refreshModule
void refreshModule(const std::string &path, const std::string &modName)
Definition: OperationIndex.cc:272
FileSystem.hh
ObjectState::stringAttribute
std::string stringAttribute(const std::string &name) const
Definition: ObjectState.cc:249
OperationIndex::opDefinitions_
DefinitionTable opDefinitions_
Contains all operation definitions defined in available operation modules indexed by module names.
Definition: OperationIndex.hh:110
OperationIndex::brokenModules_
std::set< const OperationModule * > brokenModules_
Definition: OperationIndex.hh:117
OutOfRange
Definition: Exception.hh:320
MapTools.hh
SequenceTools.hh
Operation::OPRN_NAME
static const char * OPRN_NAME
Object state name for name.
Definition: Operation.hh:67
ObjectState
Definition: ObjectState.hh:59
OperationIndex::modules_
std::vector< OperationModule * > modules_
Container holding all modules.
Definition: OperationIndex.hh:112
OperationBehaviorLoader.hh
FileSystem::globPath
static void globPath(const std::string &pattern, std::vector< std::string > &filenames)
Definition: FileSystem.cc:197
FileSystem::fileOfPath
static std::string fileOfPath(const std::string pathName)
Definition: FileSystem.cc:101
PathNotFound
Definition: Exception.hh:242
StringTools.hh
assert
#define assert(condition)
Definition: Application.hh:86
OperationIndex::PROPERTY_FILE_EXTENSION
static const std::string PROPERTY_FILE_EXTENSION
Definition: OperationIndex.hh:61
TCEString::ciEqual
bool ciEqual(const TCEString &other) const
Definition: TCEString.cc:63
SequenceTools::deleteAllItems
static void deleteAllItems(SequenceType &aSequence)
OperationModule::propertiesModule
virtual std::string propertiesModule() const
Definition: OperationModule.cc:121
Operation::setBehavior
virtual void setBehavior(OperationBehavior &behavior)
Definition: Operation.cc:378
OperationIndex::proxies_
std::vector< OperationBehaviorProxy * > proxies_
Definition: OperationIndex.hh:116
OperationBuilder
Definition: OperationBuilder.hh:42
OperationIndex::addModule
void addModule(OperationModule *module, const std::string &path)
Definition: OperationIndex.cc:193
OperationBehaviorProxy
Definition: OperationBehaviorProxy.hh:58
OperationIndex.hh
OperationSerializer::readState
virtual ObjectState * readState()
Definition: OperationSerializer.cc:118
Application.hh
__func__
#define __func__
Definition: Application.hh:67
ObjectState.hh
Operation::loadState
virtual void loadState(const ObjectState *state)
Definition: Operation.cc:480
OperationIndex::paths_
std::vector< std::string > paths_
List of paths searched for the operation modules.
Definition: OperationIndex.hh:104
ObjectState::child
ObjectState * child(int index) const
Definition: ObjectState.cc:471
Operation.hh
ObjectState::childCount
int childCount() const
SerializerException
Definition: Exception.hh:675
OperationSerializer::setSourceFile
void setSourceFile(const std::string &filename)
Definition: OperationSerializer.cc:536
OperationIndex::readOperations
void readOperations(const OperationModule &module)
Definition: OperationIndex.cc:386
Operation
Definition: Operation.hh:59
Exception::errorMessage
std::string errorMessage() const
Definition: Exception.cc:123
FileSystem::DIRECTORY_SEPARATOR
static const std::string DIRECTORY_SEPARATOR
Definition: FileSystem.hh:189
OperationIndex::loader_
OperationBehaviorLoader loader_
Definition: OperationIndex.hh:115
OperationIndex::~OperationIndex
virtual ~OperationIndex()
Definition: OperationIndex.cc:67
OperationBuilder::buildObject
bool buildObject(const std::string &baseName, const std::string &behaviorFile, const std::string &path, std::vector< std::string > &output)
Definition: OperationBuilder.cc:141
OperationIndex::modulesInPath_
ModuleTable modulesInPath_
Contains all operation modules found in a search path organized by path names.
Definition: OperationIndex.hh:107
NullOperationBehavior::instance
static NullOperationBehavior & instance()
Definition: OperationBehavior.hh:95
OperationIndex::moduleCount
int moduleCount() const
BadOperationModule
Definition: Exception.hh:785
FileSystem::fileExists
static bool fileExists(const std::string fileName)
OperationModule
Definition: OperationModule.hh:46
OperationIndex::effectiveOperation
Operation * effectiveOperation(const TCEString &name)
Definition: OperationIndex.cc:454
AssocTools.hh
TCEString
Definition: TCEString.hh:53
OperationIndex::path
std::string path(int i) const
OperationIndex::OperationIndex
OperationIndex()
Definition: OperationIndex.cc:58
OperationIndex::removeModule
void removeModule(const std::string &path, const std::string &modName)
Definition: OperationIndex.cc:212
OperationIndex::serializer_
OperationSerializer serializer_
Reads the operation property definitions.
Definition: OperationIndex.hh:114
FileSystem::STRING_WILD_CARD
static const std::string STRING_WILD_CARD
Definition: FileSystem.hh:191
NullOperationModule::instance
static NullOperationModule & instance()
FileSystem::fileNameBody
static std::string fileNameBody(const std::string &fileName)
Definition: FileSystem.cc:291
OperationIndex::operationCount
int operationCount(const OperationModule &om)
Definition: OperationIndex.cc:363
OperationBuilder.hh
AssocTools::deleteAllValues
static void deleteAllValues(ContainerType &aMap)
OperationIndex::module
OperationModule & module(int i)
OperationIndex::moduleOf
OperationModule & moduleOf(const std::string &name)
Definition: OperationIndex.cc:315
OperationIndex::operationName
std::string operationName(int i, const OperationModule &om)
Definition: OperationIndex.cc:337
OperationModule.hh
InstanceNotFound
Definition: Exception.hh:304
OperationBuilder::instance
static OperationBuilder & instance()
Definition: OperationBuilder.cc:71