![]() |
|
|
Generated: 8 Jan 2009 |

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