![]() |
|
|
Generated: 24 Nov 2008 |

Definition at line 70 of file genconf.cpp.
Public Member Functions | |
| configGenerator (const string &pkgName, const string &outputDirName) | |
| int | genConfig (const Strings_t &modules) |
main entry point of this class:
| |
| void | setConfigurableModule (const std::string &moduleName) |
| customize the Module name where configurable base classes are defined | |
| void | setConfigurableDefaultName (const std::string &defaultName) |
| customize the default name for configurable instances | |
| void | setConfigurableAlgorithm (const std::string &cfgAlgorithm) |
| customize the configurable base class for Algorithm component | |
| void | setConfigurableAlgTool (const std::string &cfgAlgTool) |
| customize the configurable base class for AlgTool component | |
| void | setConfigurableAuditor (const std::string &cfgAuditor) |
| customize the configurable base class for AlgTool component | |
| void | setConfigurableService (const std::string &cfgService) |
| customize the configurable base class for Service component | |
Private Member Functions | |
| void | genComponent (const std::string &libName, const std::string &componentName, const std::string &componentType, const vector< Property * > &properties) |
| void | genImport (std::ostream &s, const boost::format &frmt, std::string indent) |
| void | genHeader (std::ostream &pyOut, std::ostream &dbOut) |
| void | genBody (std::ostream &pyOut, std::ostream &dbOut) |
| void | genTrailer (std::ostream &pyOut, std::ostream &dbOut) |
| void | pythonizeValue (const Property *prop, string &pvalue, string &ptype) |
| handle the "marshalling" of Properties | |
| void | pythonizeName (string &name) |
| Translates a valid C++ typename into a valid python one. | |
Private Attributes | |
| string | m_pkgName |
| name of the package we are processing | |
| string | m_outputDirName |
| absolute path to the directory where genconf will store auto-generated files (Configurables and ConfigurableDb) | |
| stringstream | m_pyBuf |
| buffer of auto-generated configurables | |
| bool | m_importGaudiHandles |
| switch to decide if the generated configurables need to import GaudiHandles (ie: if one of the components has a XyzHandle<T>) | |
| stringstream | m_dbBuf |
| buffer of generated configurables informations for the "Db" file The "Db" file is holding informations about the generated configurables This file is later one used by the PropertyProxy.py to locate Configurables and know their default values, host module,. | |
| GaudiUtils::HashMap < std::string, std::string > | m_configurable |
| Configurable customization. | |
| configGenerator::configGenerator | ( | const string & | pkgName, | |
| const string & | outputDirName | |||
| ) | [inline] |
Definition at line 100 of file genconf.cpp.
00101 : 00102 m_pkgName ( pkgName ), 00103 m_outputDirName ( outputDirName ), 00104 m_pyBuf ( ), 00105 m_importGaudiHandles( false ), 00106 m_dbBuf ( ), 00107 m_configurable ( ) 00108 {}
| int configGenerator::genConfig | ( | const Strings_t & | modules | ) |
main entry point of this class:
not enough information... skip it
no Properties, so don't bother create Configurables...
: no Configurable for this component. yet... continue;
write-out files for this library
Definition at line 408 of file genconf.cpp.
00410 { 00411 //--- Disable checking StatusCode ------------------------------------------- 00412 StatusCode::disableChecking(); 00413 00414 const Strings_t::const_iterator endLib = libs.end(); 00415 00416 const std::string gaudiSvc = "GaudiSvc"; 00417 const bool isGaudiSvc = ( std::find( libs.begin(), endLib, gaudiSvc ) != endLib ); 00418 00419 //--- Instantiate ApplicationMgr -------------------------------------------- 00420 if ( !isGaudiSvc && createAppMgr() ) { 00421 cout << "ERROR: ApplicationMgr can not be created. Check environment" << endl; 00422 return EXIT_FAILURE; 00423 } 00424 00425 //--- Iterate over component factories -------------------------------------- 00426 Scope factories = Scope::ByName(PLUGINSVC_FACTORY_NS); 00427 if ( !factories ) { 00428 cout << "ERROR: No PluginSvc factory namespace could be found" << endl; 00429 return EXIT_FAILURE; 00430 } 00431 00432 ISvcLocator* svcLoc = Gaudi::svcLocator(); 00433 IService* dummySvc = new Service( "DummySvc", svcLoc ); 00434 dummySvc->addRef(); 00435 00436 bool allGood = true; 00437 00438 // iterate over all the requested libraries 00439 for ( Strings_t::const_iterator iLib=libs.begin(); iLib != endLib; ++iLib ) { 00440 00441 std::cout << ":::: processing library: " << *iLib << "..." << std::endl; 00442 00443 // reset state 00444 m_importGaudiHandles = false; 00445 m_pyBuf.str(""); 00446 m_dbBuf.str(""); 00447 00448 // Scan the pluginSvc namespace and store the "background" of already 00449 // alived components, so we can extract our signal later on 00450 set<string> bkgNames; 00451 if ( !isGaudiSvc ) { 00452 for ( Member_Iterator it = factories.FunctionMember_Begin(); 00453 it != factories.FunctionMember_End(); ++it ) { 00454 string ident = getId(*it); 00455 if ( PluginService::Debug() > 0 ) { 00456 cout << "::: " << ident << endl; 00457 } 00458 bkgNames.insert( ident ); 00459 } 00460 } 00461 const set<string>::const_iterator bkgNamesEnd = bkgNames.end(); 00462 00463 //--- Load component library ---------------------------------------------- 00464 System::ImageHandle handle; 00465 unsigned long err = System::loadDynamicLib( *iLib, &handle ); 00466 if ( err != 1 ) { 00467 cout << "ERROR: " << System::getLastErrorString() << endl; 00468 allGood = false; 00469 continue; 00470 } 00471 00472 for ( Member_Iterator it = factories.FunctionMember_Begin(); 00473 it != factories.FunctionMember_End(); 00474 ++it ) { 00475 const string ident = getId(*it); 00476 if ( bkgNames.find(ident) != bkgNamesEnd ) { 00477 if ( PluginService::Debug() > 0 ) { 00478 cout << "\t==> skipping [" << ident << "]..." << endl; 00479 } 00480 continue; 00481 } 00482 00483 // Atlas contributed code (patch #1247) 00484 // Skip the generation of configurables if the component does not come 00485 // from the same library we are processing (i.e. we found a symbol that 00486 // is coming from a library loaded by the linker). 00487 // Windows implementation is empty. 00488 if ( !DsoUtils::inDso( *it, DsoUtils::libNativeName(*iLib) ) ) { 00489 cout << "WARNING: library [" << *iLib << "] requested factory " 00490 << "from another library [" 00491 << DsoUtils::dsoName(*it) << "]" 00492 << " ==> [" << ident << "] !!" 00493 << endl; 00494 continue; 00495 } 00496 00497 const string rtype = it->TypeOf().ReturnType().Name(); 00498 string type; 00499 bool known = true; 00500 if ( ident == "ApplicationMgr" ) type = "ApplicationMgr"; 00501 else if ( rtype == "IInterface*" ) type = "IInterface"; 00502 else if ( rtype == "IAlgorithm*" ) type = "Algorithm"; 00503 else if ( rtype == "IService*" ) type = "Service"; 00504 else if ( rtype == "IAlgTool*" ) type = "AlgTool"; 00505 else if ( rtype == "IAuditor*" ) type = "Auditor"; 00506 else if ( rtype == "IConverter*" ) type = "Converter"; 00507 else if ( rtype == "DataObject*" ) type = "DataObject"; 00508 else type = "Unknown", known = false; 00509 string name = ident; 00510 // handle possible problems with templated components 00511 boost::trim(name); 00512 00513 cout << " - component: " << name << endl; 00514 00515 if ( type == "IInterface" ) { 00518 continue; 00519 } 00520 00521 if ( type == "Converter" || type == "DataObject" ) { 00523 continue; 00524 } 00525 00526 //if ( type == "ApplicationMgr" ) { 00529 //} 00530 00531 if ( !known ) { 00532 cout << "WARNING: Unknown (return) type [" << rtype << "] !!\n" 00533 << "WARNING: component [" << ident << "] is skipped !" 00534 << endl; 00535 allGood = false; 00536 continue; 00537 } 00538 00539 string cname = "DefaultName"; 00540 Object dummy; 00541 vector<void*> args; 00542 args.reserve( 3 ); 00543 if ( type == "AlgTool" ) { 00544 args.resize( 3 ); 00545 args[0] = &cname; 00546 args[1] = &type; 00547 args[2] = dummySvc; 00548 } 00549 else { 00550 args.resize( 2 ); 00551 args[0] = &cname; 00552 args[1] = svcLoc; 00553 } 00554 IProperty* prop = 0; 00555 try { 00556 if ( type == "Algorithm" ) { 00557 IAlgorithm* obj = static_cast<IAlgorithm*>(it->Invoke(dummy,args).Address()); 00558 prop = dynamic_cast<IProperty*>(obj); 00559 } 00560 else if ( type == "Service") { 00561 IService* obj = static_cast<IService*>(it->Invoke(dummy,args).Address()); 00562 prop = dynamic_cast<IProperty*>(obj); 00563 } 00564 else if ( type == "AlgTool") { 00565 IAlgTool* obj = static_cast<IAlgTool*>(it->Invoke(dummy,args).Address()); 00566 prop = dynamic_cast<IProperty*>(obj); 00567 } 00568 else if ( type == "Auditor") { 00569 IAuditor* obj = static_cast<IAuditor*>(it->Invoke(dummy,args).Address()); 00570 prop = dynamic_cast<IProperty*>(obj); 00571 } 00572 else if ( type == "ApplicationMgr") { 00573 //svcLoc->queryInterface(IProperty::interfaceID(), pp_cast<void>(&prop)); 00574 svcLoc->queryInterface(IProperty::interfaceID(), (void**)(&prop)); 00575 } 00576 else { 00577 IInterface* obj = static_cast<IInterface*>(it->Invoke(dummy,args).Address()); 00578 prop = dynamic_cast<IProperty*>(obj); 00579 } 00580 } 00581 catch ( exception& e ) { 00582 cout << "ERROR: Error instantiating " << name 00583 << " from " << *iLib << endl; 00584 cout << "ERROR: Got exception: " << e.what() << endl; 00585 allGood = false; 00586 continue; 00587 } 00588 catch ( ... ) { 00589 cout << "ERROR: Error instantiating " << name 00590 << " from " << *iLib << endl; 00591 allGood = false; 00592 continue; 00593 } 00594 if( prop ) { 00595 genComponent( *iLib, name, type, prop->getProperties() ); 00596 prop->release(); 00597 } else { 00598 cout << "ERROR: could not cast IInterface* object to an IProperty* !\n" 00599 << "ERROR: return type from PluginSvc is [" << rtype << "]...\n" 00600 << "ERROR: NO Configurable will be generated for [" 00601 << name << "] !" 00602 << endl; 00603 allGood = false; 00604 } 00605 } //> end loop over factories 00606 00610 const std::string pyName = ( fs::path(m_outputDirName) / 00611 fs::path(*iLib+"Conf.py") ).string(); 00612 const std::string dbName = ( fs::path(m_outputDirName) / 00613 fs::path(*iLib+"_confDb.py") ).string(); 00614 00615 std::fstream py( pyName.c_str(), 00616 std::ios_base::out|std::ios_base::trunc ); 00617 std::fstream db( dbName.c_str(), 00618 std::ios_base::out|std::ios_base::trunc ); 00619 00620 genHeader ( py, db ); 00621 genBody ( py, db ); 00622 genTrailer( py, db ); 00623 00624 } //> end loop over libraries 00625 00626 dummySvc->release(); 00627 dummySvc = 0; 00628 00629 return allGood ? EXIT_SUCCESS : EXIT_FAILURE; 00630 }
| void configGenerator::setConfigurableModule | ( | const std::string & | moduleName | ) | [inline] |
customize the Module name where configurable base classes are defined
Definition at line 117 of file genconf.cpp.
00118 { 00119 m_configurable[ "Module" ] = moduleName; 00120 }
| void configGenerator::setConfigurableDefaultName | ( | const std::string & | defaultName | ) | [inline] |
customize the default name for configurable instances
Definition at line 123 of file genconf.cpp.
00124 { 00125 m_configurable[ "DefaultName" ] = defaultName; 00126 }
| void configGenerator::setConfigurableAlgorithm | ( | const std::string & | cfgAlgorithm | ) | [inline] |
customize the configurable base class for Algorithm component
Definition at line 129 of file genconf.cpp.
00130 { 00131 m_configurable[ "Algorithm" ] = cfgAlgorithm; 00132 }
| void configGenerator::setConfigurableAlgTool | ( | const std::string & | cfgAlgTool | ) | [inline] |
customize the configurable base class for AlgTool component
Definition at line 135 of file genconf.cpp.
00136 { 00137 m_configurable[ "AlgTool" ] = cfgAlgTool; 00138 }
| void configGenerator::setConfigurableAuditor | ( | const std::string & | cfgAuditor | ) | [inline] |
customize the configurable base class for AlgTool component
Definition at line 141 of file genconf.cpp.
00142 { 00143 m_configurable[ "Auditor" ] = cfgAuditor; 00144 }
| void configGenerator::setConfigurableService | ( | const std::string & | cfgService | ) | [inline] |
customize the configurable base class for Service component
Definition at line 147 of file genconf.cpp.
00148 { 00149 m_configurable[ "Service" ] = cfgService; 00150 m_configurable[ "ApplicationMgr" ] = cfgService; 00151 }
| void configGenerator::genComponent | ( | const std::string & | libName, | |
| const std::string & | componentName, | |||
| const std::string & | componentType, | |||
| const vector< Property * > & | properties | |||
| ) | [private] |
Definition at line 722 of file genconf.cpp.
00727 { 00728 string cname = componentName; 00729 pythonizeName(cname); 00730 00731 typedef GaudiUtils::HashMap<std::string, std::string> PropertyDoc_t; 00732 PropertyDoc_t propDoc; 00733 00734 m_pyBuf << "\n"; 00735 m_pyBuf << "class " << cname 00736 << "( " << m_configurable[componentType] << " ) :" 00737 << "\n"; 00738 m_pyBuf << " __slots__ = { \n"; 00739 for ( vector<Property*>::const_iterator it = properties.begin() ; 00740 it != properties.end(); ++it ) { 00741 const string pname = (*it)->name(); 00742 string pvalue, ptype; 00743 pythonizeValue( (*it), pvalue, ptype ); 00744 m_pyBuf << " '" << pname << "' : " << pvalue <<", # " << ptype << "\n"; 00745 00746 if ( (*it)->documentation() != "none" ) { 00747 propDoc[pname] = (*it)->documentation(); 00748 } 00749 00750 } 00751 m_pyBuf << " }\n"; 00752 m_pyBuf << " _propertyDocDct = { \n"; 00753 for ( PropertyDoc_t::const_iterator iProp = propDoc.begin(); 00754 iProp != propDoc.end(); 00755 ++iProp ) { 00756 m_pyBuf << std::setw(5) 00757 << "'" << iProp->first << "' : " 00758 << "\"\"\" " << iProp->second << " \"\"\",\n"; 00759 } 00760 m_pyBuf << " }\n"; 00761 00762 m_pyBuf 00763 << " def __init__(self, name = " << m_configurable["DefaultName"] 00764 << ", **kwargs):\n" 00765 << " super(" << cname << ", self).__init__(name)\n" 00766 << " for n,v in kwargs.items():\n" 00767 << " setattr(self, n, v)\n" 00768 << " def getDlls( self ):\n" 00769 << " return '" << libName << "'\n" 00770 << " def getType( self ):\n" 00771 << " return '" << componentName << "'\n" 00772 << " pass # class " << cname << "\n" 00773 << flush; 00774 00775 // name of the auto-generated module 00776 const string pyName = ( fs::path(m_outputDirName) / 00777 fs::path(libName+"Conf.py") ).string(); 00778 const string modName = fs::basename( fs::path( pyName ).leaf() ); 00779 00780 // now the db part 00781 m_dbBuf 00782 << py_tab << "cfgDb.add( configurable = '" << cname << "',\n" 00783 << py_tab << " package = '" << m_pkgName << "',\n" 00784 << py_tab << " module = '" << m_pkgName << "." << modName << "',\n" 00785 << py_tab << " lib = '" << libName << "' )\n" 00786 << flush; 00787 00788 }
| void configGenerator::genImport | ( | std::ostream & | s, | |
| const boost::format & | frmt, | |||
| std::string | indent = "" | |||
| ) | [private] |
Definition at line 632 of file genconf.cpp.
00634 { 00635 00636 std::string::size_type pos = 0, nxtpos = 0; 00637 std::string mod; 00638 00639 while ( std::string::npos != pos ){ 00640 // find end of module name 00641 nxtpos = m_configurable["Module"].find_first_of(',',pos); 00642 00643 // Prepare import string 00644 mod = m_configurable["Module"].substr(pos,nxtpos-pos); 00645 std::ostringstream import; 00646 import << boost::format(frmt) % mod; 00647 00648 // append a normal import or a try/excpet enclosed one depending 00649 // on availability of a fall-back bodule (next in the list) 00650 if ( std::string::npos == nxtpos ) { 00651 // last possible module 00652 s << indent << import.str() << "\n" << flush; 00653 pos = std::string::npos; 00654 } else { 00655 // we have a fallback for this 00656 s << indent << "try:\n" 00657 << indent << py_tab << import.str() << "\n" 00658 << indent << "except ImportError:\n" 00659 << flush; 00660 pos = nxtpos+1; 00661 } 00662 // increase indentation level for next iteration 00663 indent += py_tab; 00664 } 00665 }
| void configGenerator::genHeader | ( | std::ostream & | pyOut, | |
| std::ostream & | dbOut | |||
| ) | [private] |
Definition at line 668 of file genconf.cpp.
00671 { 00672 // python file part 00673 time_t rawtime; 00674 time( &rawtime ); 00675 py << "#" << ctime(&rawtime) //<< "\n" 00676 << "\"\"\"Automatically generated. DO NOT EDIT please\"\"\"\n"; 00677 if ( m_importGaudiHandles ) { 00678 py << "from GaudiKernel.GaudiHandles import *\n"; 00679 } 00680 00681 genImport(py,boost::format("from %1%.Configurable import *")); 00682 00683 // db file part 00684 db << "## -*- python -*- \n" 00685 << "# db file automatically generated by genconf on: " 00686 << ctime(&rawtime); // << "\n"; 00687 db << "## insulates outside world against anything bad that could happen\n" 00688 << "## also prevents global scope pollution\n" 00689 << "def _fillCfgDb():\n"; 00690 genImport(db,boost::format("from %1%.ConfigurableDb import CfgDb"),py_tab); 00691 00692 db << "\n" 00693 << py_tab << "# get a handle on the repository of Configurables\n" 00694 << py_tab << "cfgDb = CfgDb()\n" 00695 << "\n" 00696 << py_tab << "# populate the repository with informations on Configurables \n" 00697 << "\n" 00698 << flush; 00699 }
| void configGenerator::genBody | ( | std::ostream & | pyOut, | |
| std::ostream & | dbOut | |||
| ) | [inline, private] |
| void configGenerator::genTrailer | ( | std::ostream & | pyOut, | |
| std::ostream & | dbOut | |||
| ) | [private] |
Definition at line 701 of file genconf.cpp.
00704 { 00705 // db file part 00706 db << py_tab << "return #_fillCfgDb\n" 00707 << "# fill cfgDb at module import...\n" 00708 << "try:\n" 00709 << py_tab << "_fillCfgDb()\n" 00710 << py_tab << "#house cleaning...\n" 00711 << py_tab << "del _fillCfgDb\n" 00712 << "except Exception,err:\n" 00713 << py_tab << "print \"Py:ConfigurableDb ERROR Problem with [%s] content!" 00714 << "\" % __name__\n" 00715 << py_tab << "print \"Py:ConfigurableDb ERROR\",err\n" 00716 << py_tab << "print \"Py:ConfigurableDb ERROR ==> culprit is package [" 00717 << m_pkgName << "] !\"\n" 00718 << std::flush; 00719 }
| void configGenerator::pythonizeValue | ( | const Property * | prop, | |
| string & | pvalue, | |||
| string & | ptype | |||
| ) | [private] |
handle the "marshalling" of Properties
Definition at line 801 of file genconf.cpp.
00804 { 00805 const std::string cvalue = p->toString(); 00806 const type_info& ti = *p->type_info(); 00807 if ( ti == typeid(bool) ) { 00808 pvalue = ( cvalue == "0" || cvalue == "False" || cvalue == "false" ) 00809 ? "False" 00810 : "True"; 00811 ptype = "bool"; 00812 } 00813 else if ( ti == typeid(char) || ti == typeid(signed char) 00814 || ti == typeid(unsigned char) || 00815 ti == typeid(short) || ti == typeid(unsigned short) || 00816 ti == typeid(int) || ti == typeid(unsigned int) || 00817 ti == typeid(long) || ti == typeid(unsigned long) ) { 00818 pvalue = cvalue; 00819 ptype = "int"; 00820 } 00821 else if ( ti == typeid(long long) || ti == typeid(unsigned long long) ) { 00822 pvalue = cvalue + "L"; 00823 ptype = "long"; 00824 } 00825 else if ( ti == typeid(float) || ti == typeid(double) ) { 00826 // forces python to handle this as a float: put a dot in there... 00827 pvalue = boost::to_lower_copy(cvalue); 00828 if ( pvalue == "nan" ) { 00829 pvalue = "float('nan')"; 00830 std::cout << "WARNING: default value for [" 00831 << p->name() << "] is NaN !!" 00832 << std::endl; 00833 } else if ( std::string::npos == pvalue.find(".") && 00834 std::string::npos == pvalue.find("e") ) { 00835 pvalue = cvalue + ".0"; 00836 } 00837 ptype = "float"; 00838 } 00839 else if ( ti == typeid(string) ) { 00840 00841 pvalue = "'"+cvalue+"'"; 00842 ptype = "str"; 00843 } 00844 else if ( ti == typeid(GaudiHandleBase) ) { 00845 m_importGaudiHandles = true; 00846 const GaudiHandleProperty& hdl 00847 = dynamic_cast<const GaudiHandleProperty&>(*p); 00848 const GaudiHandleBase& base = hdl.value(); 00849 00850 pvalue = base.pythonRepr(); 00851 ptype = "GaudiHandle"; 00852 } 00853 else if ( ti == typeid(GaudiHandleArrayBase) ) { 00854 m_importGaudiHandles = true; 00855 const GaudiHandleArrayProperty& hdl 00856 = dynamic_cast<const GaudiHandleArrayProperty&>(*p); 00857 const GaudiHandleArrayBase& base = hdl.value(); 00858 00859 pvalue = base.pythonRepr(); 00860 ptype = "GaudiHandleArray"; 00861 } 00862 else { 00863 pvalue = cvalue; 00864 ptype = "list"; 00865 } 00866 }
| void configGenerator::pythonizeName | ( | string & | name | ) | [private] |
Translates a valid C++ typename into a valid python one.
Definition at line 790 of file genconf.cpp.
00792 { 00793 static string in("<>&*,: ()."); 00794 static string out("__rp__s___"); 00795 for ( string::iterator i = name.begin(); i != name.end(); ++i ) { 00796 if ( in.find(*i) != string::npos ) *i = out[in.find(*i)]; 00797 } 00798 }
string configGenerator::m_pkgName [private] |
string configGenerator::m_outputDirName [private] |
absolute path to the directory where genconf will store auto-generated files (Configurables and ConfigurableDb)
Definition at line 77 of file genconf.cpp.
stringstream configGenerator::m_pyBuf [private] |
bool configGenerator::m_importGaudiHandles [private] |
switch to decide if the generated configurables need to import GaudiHandles (ie: if one of the components has a XyzHandle<T>)
Definition at line 84 of file genconf.cpp.
stringstream configGenerator::m_dbBuf [private] |
buffer of generated configurables informations for the "Db" file The "Db" file is holding informations about the generated configurables This file is later one used by the PropertyProxy.py to locate Configurables and know their default values, host module,.
..
Definition at line 90 of file genconf.cpp.
GaudiUtils::HashMap<std::string, std::string> configGenerator::m_configurable [private] |
Configurable customization.
Contains customization for:
Definition at line 97 of file genconf.cpp.