|
Gaudi Framework, version v21r8 |
| Home | Generated: 17 Mar 2010 |

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