OpenASIP 2.2
Loading...
Searching...
No Matches
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
49using std::map;
50using std::string;
51using std::vector;
52
53const string OperationIndex::PROPERTY_FILE_EXTENSION = ".opp";
54
55/**
56 * Constructor.
57 */
59}
60
61/**
62 * Destructor.
63 *
64 * Deletes all object state trees modeling module properties. Deletes all
65 * modules.
66 */
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 */
81void
82OperationIndex::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 }
132 OperationModule* module =
133 new OperationModule(FileSystem::fileNameBody(file), path);
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 */
151OperationIndex::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 */
174int
175OperationIndex::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 */
192void
193OperationIndex::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 */
211void
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 */
271void
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 */
315OperationIndex::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 */
336string
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);
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 */
362int
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 */
385void
389 opDefinitions_[module.propertiesModule()] = tree;
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);
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 */
455
456 OperationModule& mod = moduleOf(name);
457
458 DefinitionTable::const_iterator dt =
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 =
486 proxies_.push_back(proxy);
487 oper->setBehavior(*proxy);
488 return oper;
489 }
490 return NULL;
491}
#define __func__
#define assert(condition)
static void deleteAllValues(ContainerType &aMap)
std::string errorMessage() const
Definition Exception.cc:123
static void globPath(const std::string &pattern, std::vector< std::string > &filenames)
static const std::string DIRECTORY_SEPARATOR
static std::string fileOfPath(const std::string pathName)
static const std::string STRING_WILD_CARD
static bool fileExists(const std::string fileName)
static NullOperationBehavior & instance()
static NullOperationModule & instance()
ObjectState * child(int index) const
std::string stringAttribute(const std::string &name) const
int childCount() const
static OperationBuilder & instance()
bool buildObject(const std::string &baseName, const std::string &behaviorFile, const std::string &path, std::vector< std::string > &output)
OperationSerializer serializer_
Reads the operation property definitions.
void readOperations(const OperationModule &module)
static const std::string PROPERTY_FILE_EXTENSION
virtual ~OperationIndex()
ModuleTable modulesInPath_
Contains all operation modules found in a search path organized by path names.
DefinitionTable opDefinitions_
Contains all operation definitions defined in available operation modules indexed by module names.
std::string operationName(int i, const OperationModule &om)
OperationModule & module(int i)
Operation * effectiveOperation(const TCEString &name)
void removeModule(const std::string &path, const std::string &modName)
std::string path(int i) const
std::set< const OperationModule * > brokenModules_
OperationModule & moduleOf(const std::string &name)
std::vector< std::string > paths_
List of paths searched for the operation modules.
void addModule(OperationModule *module, const std::string &path)
std::vector< OperationBehaviorProxy * > proxies_
void addPath(const std::string &path)
int operationCount(const OperationModule &om)
OperationBehaviorLoader loader_
int moduleCount() const
void refreshModule(const std::string &path, const std::string &modName)
std::vector< OperationModule * > modules_
Container holding all modules.
virtual std::string propertiesModule() const
void setSourceFile(const std::string &filename)
virtual ObjectState * readState()
virtual void setBehavior(OperationBehavior &behavior)
Definition Operation.cc:378
static const char * OPRN_NAME
Object state name for name.
Definition Operation.hh:67
virtual void loadState(const ObjectState *state)
Definition Operation.cc:480
static void deleteAllItems(SequenceType &aSequence)
bool ciEqual(const TCEString &other) const
Definition TCEString.cc:63