|
libFAUDES
Sections
Index
|
cfl_registry.cppGo to the documentation of this file.00001 /** @file cfl_registry.cpp Runtime interface, registry for faudes types and functions */ 00002 00003 /* FAU Discrete Event Systems Library (libfaudes) 00004 00005 Copyright (C) 2009 Ruediger Berndt 00006 Copyright (C) 2009 Thomas Moor 00007 00008 This library is free software; you can redistribute it and/or 00009 modify it under the terms of the GNU Lesser General Public 00010 License as published by the Free Software Foundation; either 00011 version 2.1 of the License, or (at your option) any later version. 00012 00013 This library is distributed in the hope that it will be useful, 00014 but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00016 Lesser General Public License for more details. 00017 00018 You should have received a copy of the GNU Lesser General Public 00019 License along with this library; if not, write to the Free Software 00020 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ 00021 00022 00023 00024 #include "cfl_registry.h" 00025 #include "corefaudes.h" 00026 00027 // auto install types 00028 #ifndef FAUDES_MUTE_RTIAUTOLOAD 00029 #include "allplugins.h" 00030 #include "rtiautoload.h" 00031 #include "rtiautoload.cpp" 00032 #endif 00033 00034 namespace faudes{ 00035 00036 00037 00038 /* 00039 ******************************************************************** 00040 ******************************************************************** 00041 ******************************************************************** 00042 00043 Implemantation of faudes TypeRegistry 00044 00045 ******************************************************************** 00046 ******************************************************************** 00047 ******************************************************************** 00048 */ 00049 00050 // static members: ref to the only one instnace 00051 TypeRegistry* TypeRegistry::mpInstance = 0; 00052 00053 // static member: access to signleton 00054 TypeRegistry* TypeRegistry::G(){ 00055 // lazy initialization 00056 if(!mpInstance){ 00057 FD_DRTI("TypeRegistry::G(): Constrtuct singleton"); 00058 mpInstance = new TypeRegistry(); 00059 } 00060 return(mpInstance); 00061 } 00062 00063 // clear all 00064 void TypeRegistry::Clear(){ 00065 // delete all typedefs contained in map 00066 std::map<std::string, TypeDefinition*>::iterator mit; 00067 for(mit = mNameToTypeDef.begin(); mit != mNameToTypeDef.end(); mit++){ 00068 if(mit->second != NULL){ 00069 delete mit->second; 00070 mit->second = NULL; 00071 } 00072 } 00073 // delete maps 00074 mNameToTypeDef.clear(); 00075 mIdToTypeDef.clear(); 00076 } 00077 00078 // query number of entries 00079 int TypeRegistry::Size() const{ 00080 return(mNameToTypeDef.size()); 00081 } 00082 00083 // read access on type map 00084 TypeRegistry::Iterator TypeRegistry::Begin(void) const{ 00085 return(mNameToTypeDef.begin()); 00086 } 00087 00088 // read access on type map 00089 TypeRegistry::Iterator TypeRegistry::End(void) const{ 00090 return(mNameToTypeDef.end()); 00091 } 00092 00093 // insert new entry 00094 void TypeRegistry::Insert(TypeDefinition* pTypeDef){ 00095 FD_DRTI("TypeRegistration::Insert(): definition for " << pTypeDef->Name()); 00096 // test existence 00097 if(Exists(pTypeDef->Name())){ 00098 std::stringstream err; 00099 err << "Cannot overwrite existing entry with type " << pTypeDef->Name() << std::endl; 00100 throw Exception("TypeRegistry::Insert()", err.str(), 46); 00101 } 00102 // record in main map 00103 mNameToTypeDef[pTypeDef->Name()]=pTypeDef; 00104 // record in id map (first entry wins) 00105 if(pTypeDef->Prototype()) 00106 if(mIdToTypeDef.find(typeid(*(pTypeDef->Prototype())).name())== 00107 mIdToTypeDef.end()) 00108 mIdToTypeDef[typeid(*(pTypeDef->Prototype())).name()]=pTypeDef; 00109 } 00110 00111 00112 // scan token stream for type definitions 00113 void TypeRegistry::MergeDocumentation(TokenReader& rTr) { 00114 FD_DRTI("TypeRegistration::MergeMergeDocumentation()"); 00115 // scan file 00116 Token token; 00117 while(rTr.Peek(token)) { 00118 // continue on other tokens 00119 if(token.Type()!=Token::Begin) { rTr.Get(token); continue; } 00120 if(token.StringValue()!="TypeDefinition") { rTr.Get(token); continue; } 00121 // found type def in file 00122 rTr.ReadBegin("TypeDefinition"); 00123 rTr.Peek(token); 00124 std::string ftype=token.StringValue(); 00125 // extract type name 00126 size_t pos=ftype.find("::"); 00127 if(pos!=std::string::npos) ftype=ftype.substr(pos+2); 00128 // locate type def in map 00129 Iterator tit = mNameToTypeDef.find(ftype); 00130 // case 1: type exists: add documentaion 00131 if(tit!=mNameToTypeDef.end()) { 00132 tit->second->MergeDocumentationBody(rTr); 00133 rTr.ReadEnd("TypeDefinition"); 00134 continue; 00135 } 00136 // case 2: type does not exist: insert fake entry 00137 TypeDefinition* tdef = new TypeDefinition(ftype); 00138 tdef->MergeDocumentationBody(rTr); 00139 Insert(tdef); 00140 rTr.ReadEnd("TypeDefinition"); 00141 } 00142 } 00143 00144 // scan file for type definitions 00145 void TypeRegistry::MergeDocumentation(const std::string& rFileName) { 00146 TokenReader tr(rFileName); 00147 MergeDocumentation(tr); 00148 } 00149 00150 00151 // construct faudes object by typename 00152 Type* TypeRegistry::NewObject(const std::string& rName) const{ 00153 FD_DRTI("TypeRegistry::NewObject(\"" << rName << "\")"); 00154 Iterator mit=mNameToTypeDef.find(rName); 00155 if(mit == End()) { 00156 std::stringstream err; 00157 err << "Unknown Type " << rName << std::endl; 00158 throw Exception("TypeRegistry::NewObject()", err.str(), 47); 00159 } 00160 Type* res=mit->second->NewObject(); 00161 if(!res) { 00162 std::stringstream err; 00163 err << "Failed to instatiate new " << rName << std::endl; 00164 throw Exception("TypeRegistry::NewObject()", err.str(), 47); 00165 } 00166 return res; 00167 } 00168 00169 // construct faudes object by typed reference 00170 Type* TypeRegistry::NewObject(const Type& rType) const{ 00171 FD_DRTI("TypeRegistry::NewObject(prototype): typeid " << typeid(rType).name()); 00172 Iterator mit; 00173 mit=mIdToTypeDef.find(typeid(rType).name()); 00174 if(mit == mIdToTypeDef.end()) { 00175 std::stringstream err; 00176 err << "Unknown type by reference" << std::endl; 00177 throw Exception("TypeRegistry::NewObject()", err.str(), 47); 00178 } 00179 return(rType.New()); 00180 } 00181 00182 // access type definition by type name 00183 const TypeDefinition& TypeRegistry::Definition(const std::string& rName) const{ 00184 FD_DRTI("TypeRegistry::Definition( " << rName << " )"); 00185 Iterator mit=mNameToTypeDef.find(rName); 00186 if(mit == End()) { 00187 std::stringstream err; 00188 err << "Type not found: \"" << rName << "\""; 00189 throw Exception("TypeRegistry::Definition()", err.str(), 46); 00190 } 00191 return(*(mit->second)); 00192 } 00193 00194 // access type definition by typed reference 00195 const TypeDefinition& TypeRegistry::Definition(const Type& rType) const{ 00196 FD_DRTI("TypeRegistry::Definition(): typeid " << typeid(rType).name()); 00197 Iterator mit; 00198 mit=mIdToTypeDef.find(typeid(rType).name()); 00199 if(mit!=mIdToTypeDef.end()) return *(mit->second); 00200 std::stringstream err; 00201 err << "Type not found: " << typeid(rType).name(); 00202 throw Exception("TypeRegistry::Definition()", err.str(), 46); 00203 } 00204 00205 // access prototype by type name 00206 const Type* TypeRegistry::Prototype(const std::string& rName) const{ 00207 FD_DRTI("TypeRegistry::Prototype( " << rName << " )"); 00208 Iterator mit=mNameToTypeDef.find(rName); 00209 if(mit == End()) return 0; 00210 return(mit->second->Prototype()); 00211 } 00212 00213 // access type definition by typed reference 00214 const std::string& TypeRegistry::TypeName(const Type& rType) const{ 00215 FD_DRTI("TypeRegistry::TypeName(): typeid " << typeid(rType).name()); 00216 Iterator mit; 00217 mit=mIdToTypeDef.find(typeid(rType).name()); 00218 if(mit!=mIdToTypeDef.end()) return mit->second->Name(); 00219 static std::string empty(""); 00220 return empty; 00221 } 00222 00223 // test existsnce by type name 00224 bool TypeRegistry::Exists(const std::string& rName) const{ 00225 return mNameToTypeDef.find(rName) != End(); 00226 } 00227 00228 // test existsnce by type name 00229 bool TypeRegistry::Exists(const Type& rType) const{ 00230 return mIdToTypeDef.find(typeid(rType).name()) != mIdToTypeDef.end(); 00231 } 00232 00233 00234 // token write (informative/debugging) 00235 void TypeRegistry::DoWrite(TokenWriter& rTw, const std::string& rLabel, const Type* pContext) const { 00236 FD_DRTI("TypeRegistry::DoWrite(): file " << rTw.FileName()); 00237 // ignore label and context 00238 (void) rLabel; 00239 (void) pContext; 00240 // doit 00241 rTw.WriteBegin("TypeRegistry"); 00242 Iterator tit; 00243 for(tit=Begin();tit!=End();tit++) { 00244 // write type definition 00245 tit->second->Write(rTw); 00246 } 00247 rTw.WriteEnd("TypeRegistry"); 00248 } 00249 00250 00251 /* 00252 ******************************************************************** 00253 ******************************************************************** 00254 ******************************************************************** 00255 00256 Implemantation of faudes FunctionRegistry 00257 00258 ******************************************************************** 00259 ******************************************************************** 00260 ******************************************************************** 00261 */ 00262 00263 // static members: ref to the only one instnace 00264 FunctionRegistry* FunctionRegistry::mpInstance = 0; 00265 00266 // static member: access to signleton 00267 FunctionRegistry* FunctionRegistry::G(){ 00268 // lazy initialization 00269 if(!mpInstance){ 00270 FD_DRTI("FunctionRegistry::G(): Construct singleton"); 00271 mpInstance = new FunctionRegistry(); 00272 } 00273 return(mpInstance); 00274 } 00275 00276 // clear all 00277 void FunctionRegistry::Clear(){ 00278 // delete all functiondefs contained in map 00279 std::map<std::string, FunctionDefinition*>::iterator mit; 00280 for(mit = mNameToFunctionDef.begin(); mit != mNameToFunctionDef.end(); mit++){ 00281 if(mit->second != NULL) { 00282 FD_DRTI("FunctionRegistry::Clear: removing " << mit->second->Name()); 00283 delete mit->second; 00284 mit->second = NULL; 00285 } 00286 } 00287 // delete maps 00288 mNameToFunctionDef.clear(); 00289 mIdToFunctionDef.clear(); 00290 } 00291 00292 // query number of entries 00293 int FunctionRegistry::Size() const{ 00294 return(mNameToFunctionDef.size()); 00295 } 00296 00297 // read access on function map 00298 FunctionRegistry::Iterator FunctionRegistry::Begin(void) const{ 00299 return(mNameToFunctionDef.begin()); 00300 } 00301 00302 // read access on function map 00303 FunctionRegistry::Iterator FunctionRegistry::End(void) const{ 00304 return(mNameToFunctionDef.end()); 00305 } 00306 00307 // insert new entry 00308 void FunctionRegistry::Insert(FunctionDefinition* pFunctionDef){ 00309 FD_DRTI("FunctionRegistration::Insert(): definition for " << pFunctionDef->Name()); 00310 // test existence 00311 if(Exists(pFunctionDef->Name())){ 00312 std::stringstream err; 00313 err << "Cannot overwrite existing entry with function " << pFunctionDef->Name() << std::endl; 00314 throw Exception("FunctionRegistry::Insert()", err.str(), 46); 00315 } 00316 // record in map 00317 mNameToFunctionDef[pFunctionDef->Name()]=pFunctionDef; 00318 // record in id map 00319 if(pFunctionDef->Prototype()) 00320 mIdToFunctionDef[typeid(*(pFunctionDef->Prototype())).name()]=pFunctionDef; 00321 } 00322 00323 00324 // scan token stream for function definitions 00325 void FunctionRegistry::MergeDocumentation(TokenReader& rTr) { 00326 FD_DRTI("FunctionRegistration::MergeDocumentation()"); 00327 // scan file 00328 Token token; 00329 while(rTr.Peek(token)) { 00330 // continue on other tokens 00331 if(token.Type()!=Token::Begin) { rTr.Get(token); continue; } 00332 if(token.StringValue()!="FunctionDefinition") { rTr.Get(token); continue; } 00333 // found function def in file 00334 rTr.ReadBegin("FunctionDefinition"); 00335 rTr.Peek(token); 00336 std::string ffunction=token.StringValue(); 00337 // extract function name 00338 size_t pos=ffunction.find("::"); 00339 if(pos!=std::string::npos) ffunction=ffunction.substr(pos+2); 00340 // locate function def in map 00341 Iterator fit = mNameToFunctionDef.find(ffunction); 00342 // case 1: function exists: add documentaion 00343 if(fit!=mNameToFunctionDef.end()) { 00344 fit->second->MergeDocumentationBody(rTr); 00345 rTr.ReadEnd("FunctionDefinition"); 00346 continue; 00347 } 00348 // case 2: function does not exist: insert fake entry 00349 FunctionDefinition* fdef = new FunctionDefinition(ffunction); 00350 fdef->MergeDocumentationBody(rTr); 00351 Insert(fdef); 00352 rTr.ReadEnd("FunctionDefinition"); 00353 } 00354 } 00355 00356 // scan file for function definitions 00357 void FunctionRegistry::MergeDocumentation(const std::string& rFileName) { 00358 TokenReader tr(rFileName); 00359 MergeDocumentation(tr); 00360 } 00361 00362 00363 // construct faudes object by functionname 00364 Function* FunctionRegistry::NewFunction(const std::string& rName) const{ 00365 FD_DRTI("FunctionRegistry::NewFunction(\"" << rName << "\")"); 00366 Iterator mit=mNameToFunctionDef.find(rName); 00367 if(mit == End()) { 00368 std::stringstream err; 00369 err << "Unknown function " << rName << std::endl; 00370 throw Exception("FunctionRegistry::NewFunction()", err.str(), 47); 00371 } 00372 Function* res=mit->second->NewFunction(); 00373 if(!res) { 00374 std::stringstream err; 00375 err << "Failed to instatiate new " << rName << std::endl; 00376 throw Exception("FunctionRegistry::NewFunction()", err.str(), 47); 00377 } 00378 return res; 00379 } 00380 00381 // construct faudes object by function reference 00382 Function* FunctionRegistry::NewFunction(const Function& rFunction) const{ 00383 FD_DRTI("FunctionRegistry::NewFunction(prototype): typeid " << typeid(rFunction).name()); 00384 Iterator mit; 00385 mit=mIdToFunctionDef.find(typeid(rFunction).name()); 00386 if(mit == mIdToFunctionDef.end()) { 00387 std::stringstream err; 00388 err << "Unknown function by reference" << std::endl; 00389 throw Exception("FunctionRegistry::NewFunction()", err.str(), 47); 00390 } 00391 return(rFunction.New()); 00392 } 00393 00394 // access function definition by function name 00395 const FunctionDefinition& FunctionRegistry::Definition(const std::string& rName) const{ 00396 FD_DRTI("FunctionRegistry::Definition( " << rName << " )"); 00397 Iterator mit=mNameToFunctionDef.find(rName); 00398 if(mit == End()) { 00399 std::stringstream err; 00400 err << "Function not found: " << rName; 00401 throw Exception("FunctionRegistry::Definition()", err.str(), 46); 00402 } 00403 return(*(mit->second)); 00404 } 00405 00406 // access function definition by functiond reference 00407 // todo: have function id map 00408 const FunctionDefinition& FunctionRegistry::Definition(const Function& rFunction) const{ 00409 FD_DRTI("FunctionRegistry::Definition(): typeid " << typeid(rFunction).name()); 00410 Iterator mit; 00411 mit=mIdToFunctionDef.find(typeid(rFunction).name()); 00412 if(mit!=mIdToFunctionDef.end()) return *(mit->second); 00413 /* 00414 Iterator mit; 00415 for(mit = Begin(); mit != End(); mit++){ 00416 if(typeid(rFunction) == typeid(*(mit->second->Prototype()))) 00417 return *(mit->second); 00418 } 00419 */ 00420 std::stringstream err; 00421 err << "Function not found: " << typeid(rFunction).name(); 00422 throw Exception("FunctionRegistry::Definition()", err.str(), 46); 00423 } 00424 00425 // test existsnce by function name 00426 bool FunctionRegistry::Exists(const std::string& rName) const{ 00427 return mNameToFunctionDef.find(rName) != End(); 00428 } 00429 00430 // test existsnce by function name 00431 bool FunctionRegistry::Exists(const Function& rFunction) const{ 00432 return mIdToFunctionDef.find(typeid(rFunction).name()) != mIdToFunctionDef.end(); 00433 } 00434 00435 00436 // token write (informative/debugging) 00437 void FunctionRegistry::DoWrite(TokenWriter& rTw, const std::string& rLabel, const Type* pContext) const { 00438 FD_DRTI("FunctionRegistry::DoWrite(): file " << rTw.FileName()); 00439 // ignore label and context 00440 (void) rLabel; 00441 (void) pContext; 00442 // doit 00443 rTw.WriteBegin("FunctionRegistry"); 00444 Iterator tit; 00445 for(tit=Begin();tit!=End();tit++) { 00446 // write function definition 00447 tit->second->Write(rTw); 00448 } 00449 rTw.WriteEnd("FunctionRegistry"); 00450 } 00451 00452 00453 /* 00454 ******************************************************************** 00455 ******************************************************************** 00456 ******************************************************************** 00457 00458 Implemantation of LoadRegistry 00459 00460 ******************************************************************** 00461 ******************************************************************** 00462 ******************************************************************** 00463 */ 00464 00465 // load from file 00466 void LoadRegistry(const std::string& rPath) { 00467 FD_DRTI("LoadRegistry(" << rPath << ")"); 00468 // default path 00469 std::string rtipath = rPath; 00470 if(rtipath=="") rtipath="../doc/registry/registry.rti"; // todo: plattform/configure 00471 // clear 00472 TypeRegistry::G()->Clear(); 00473 FunctionRegistry::G()->Clear(); 00474 00475 // auto install types with rti file 00476 #ifndef FAUDES_MUTE_RTIAUTOLOAD 00477 LoadAutoregisteredTypes(); 00478 #endif 00479 00480 // install programmatic functions 00481 //FunctionRegistry::G()->Insert<RtiReachability>("Reachability Tests"); 00482 //FunctionRegistry::G()->Insert<RtiIntegerSum>("IntegerSum"); 00483 00484 // allow build system load registry programmatic contributions defined in plugins 00485 #ifdef FAUDES_PLUGINS_RTILOAD 00486 FAUDES_PLUGINS_RTILOAD; 00487 #endif 00488 00489 // auto install functions 00490 #ifndef FAUDES_MUTE_RTIAUTOLOAD 00491 LoadAutoregisteredFunctions(); 00492 #endif 00493 00494 // merge documentation 00495 TypeRegistry::G()->MergeDocumentation(rtipath); 00496 FunctionRegistry::G()->MergeDocumentation(rtipath); 00497 00498 // test and report status 00499 #ifdef FAUDES_CHECKED 00500 #ifndef FAUDES_MUTE_RTIAUTOLOAD 00501 TypeRegistry::Iterator tit; 00502 for(tit=TypeRegistry::G()->Begin(); tit!=TypeRegistry::G()->End(); tit++) { 00503 // should have prototype 00504 if(tit->second->Prototype()==NULL) 00505 FD_WARN("TypeRegistry: " << tit->second->Name() << " has no prototype"); 00506 } 00507 FunctionRegistry::Iterator fit; 00508 for(fit=FunctionRegistry::G()->Begin(); fit!=FunctionRegistry::G()->End(); fit++) { 00509 // should have prototype 00510 if(fit->second->Prototype()==NULL) 00511 FD_WARN("FunctionRegistry: " << fit->second->Name() << " has no prototype"); 00512 } 00513 #endif 00514 #endif 00515 00516 FD_DRTI("LoadRegistry(" << rPath << "): done"); 00517 } 00518 00519 // clear all 00520 void ClearRegistry(void) { 00521 FD_DRTI("ClearRegistry()"); 00522 // clear 00523 FunctionRegistry::G()->Clear(); 00524 TypeRegistry::G()->Clear(); 00525 } 00526 00527 // conveience access to singleton 00528 Type* NewObject(const std::string& rTypeName) { return TypeRegistry::G()->NewObject(rTypeName);} 00529 const std::string& TypeName(const Type& rObject) { return TypeRegistry::G()->TypeName(rObject);} 00530 Function* NewFunction(const std::string& rFunctName) { return FunctionRegistry::G()->NewFunction(rFunctName);} 00531 00532 00533 } // namespace |
libFAUDES 2.16b --- 2010-9-8 --- c++ source docu by doxygen 1.6.3