|
Gaudi Framework, version v22r0 |
| Home | Generated: 9 Feb 2011 |

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