|
Gaudi Framework, version v23r2 |
| Home | Generated: Thu Jun 28 2012 |

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 | |
| int | 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 91 of file genconf.cpp.
| configGenerator::configGenerator | ( | const string & | pkgName, |
| const string & | outputDirName | ||
| ) | [inline] |
Definition at line 121 of file genconf.cpp.
:
m_pkgName ( pkgName ),
m_outputDirName ( outputDirName ),
m_pyBuf ( ),
m_importGaudiHandles( false ),
m_dbBuf ( ),
m_configurable ( )
{}
| void configGenerator::genBody | ( | std::ostream & | pyOut, |
| std::ostream & | dbOut | ||
| ) | [inline, private] |
| int configGenerator::genComponent | ( | const std::string & | libName, |
| const std::string & | componentName, | ||
| const std::string & | componentType, | ||
| const vector< Property * > & | properties | ||
| ) | [private] |
Definition at line 749 of file genconf.cpp.
{
string cname = componentName;
pythonizeName(cname);
typedef GaudiUtils::HashMap<std::string, std::string> PropertyDoc_t;
PropertyDoc_t propDoc;
m_pyBuf << "\n";
m_pyBuf << "class " << cname
<< "( " << m_configurable[componentType] << " ) :"
<< "\n";
m_pyBuf << " __slots__ = { \n";
for ( vector<Property*>::const_iterator it = properties.begin() ;
it != properties.end(); ++it ) {
const string pname = (*it)->name();
// Validate property name (it must be a valid Python identifier)
if (!boost::regex_match(pname, pythonIdentifier)) {
std::cout << "ERROR: invalid property name \"" << pname
<< "\" in component " << cname
<< " (invalid Python identifier)" << std::endl;
// try to make the buffer at least more or less valid python code.
m_pyBuf << " #ERROR-invalid identifier '" << pname << "'\n"
<< " }\n";
return 1;
}
string pvalue, ptype;
pythonizeValue( (*it), pvalue, ptype );
m_pyBuf << " '" << pname << "' : " << pvalue <<", # " << ptype << "\n";
if ( (*it)->documentation() != "none" ) {
propDoc[pname] = (*it)->documentation();
}
}
m_pyBuf << " }\n";
m_pyBuf << " _propertyDocDct = { \n";
for ( PropertyDoc_t::const_iterator iProp = propDoc.begin();
iProp != propDoc.end();
++iProp ) {
m_pyBuf << std::setw(5)
<< "'" << iProp->first << "' : "
<< "\"\"\" " << iProp->second << " \"\"\",\n";
}
m_pyBuf << " }\n";
m_pyBuf
<< " def __init__(self, name = " << m_configurable["DefaultName"]
<< ", **kwargs):\n"
<< " super(" << cname << ", self).__init__(name)\n"
<< " for n,v in kwargs.items():\n"
<< " setattr(self, n, v)\n"
<< " def getDlls( self ):\n"
<< " return '" << libName << "'\n"
<< " def getType( self ):\n"
<< " return '" << componentName << "'\n"
<< " pass # class " << cname << "\n"
<< flush;
// name of the auto-generated module
const string pyName = ( fs::path(m_outputDirName) /
fs::path(libName+"Conf.py") ).string();
const string modName = fs::basename( fs::path( pyName ).leaf() );
// now the db part
m_dbBuf
<< py_tab << "cfgDb.add( configurable = '" << cname << "',\n"
<< py_tab << " package = '" << m_pkgName << "',\n"
<< py_tab << " module = '" << m_pkgName << "." << modName << "',\n"
<< py_tab << " lib = '" << libName << "' )\n"
<< flush;
return 0;
}
| 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 439 of file genconf.cpp.
{
//--- Disable checking StatusCode -------------------------------------------
StatusCode::disableChecking();
const Strings_t::const_iterator endLib = libs.end();
const std::string gaudiSvc = "GaudiCoreSvc";
const bool isGaudiSvc = ( std::find( libs.begin(), endLib, gaudiSvc ) != endLib );
//--- Instantiate ApplicationMgr --------------------------------------------
if ( !isGaudiSvc && createAppMgr() ) {
cout << "ERROR: ApplicationMgr can not be created. Check environment" << endl;
return EXIT_FAILURE;
}
//--- Iterate over component factories --------------------------------------
Scope factories = Scope::ByName(PLUGINSVC_FACTORY_NS);
if ( !factories ) {
cout << "ERROR: No PluginSvc factory namespace could be found" << endl;
return EXIT_FAILURE;
}
ISvcLocator* svcLoc = Gaudi::svcLocator();
IInterface* dummySvc = new Service( "DummySvc", svcLoc );
dummySvc->addRef();
bool allGood = true;
// iterate over all the requested libraries
for ( Strings_t::const_iterator iLib=libs.begin(); iLib != endLib; ++iLib ) {
std::cout << ":::: processing library: " << *iLib << "..." << std::endl;
// reset state
m_importGaudiHandles = false;
m_pyBuf.str("");
m_dbBuf.str("");
// Scan the pluginSvc namespace and store the "background" of already
// alive components, so we can extract our signal later on
set<string> bkgNames;
if ( !isGaudiSvc ) {
for ( Member_Iterator it = factories.FunctionMember_Begin();
it != factories.FunctionMember_End(); ++it ) {
string ident = getId(*it);
if ( PluginService::Debug() > 0 ) {
cout << "::: " << ident << endl;
}
bkgNames.insert( ident );
}
}
const set<string>::const_iterator bkgNamesEnd = bkgNames.end();
//--- Load component library ----------------------------------------------
System::ImageHandle handle;
unsigned long err = System::loadDynamicLib( *iLib, &handle );
if ( err != 1 ) {
cout << "ERROR: " << System::getLastErrorString() << endl;
allGood = false;
continue;
}
for ( Member_Iterator it = factories.FunctionMember_Begin();
it != factories.FunctionMember_End();
++it ) {
const string ident = getId(*it);
if ( bkgNames.find(ident) != bkgNamesEnd ) {
if ( PluginService::Debug() > 0 ) {
cout << "\t==> skipping [" << ident << "]..." << endl;
}
continue;
}
// Atlas contributed code (patch #1247)
// Skip the generation of configurables if the component does not come
// from the same library we are processing (i.e. we found a symbol that
// is coming from a library loaded by the linker).
// Windows implementation is empty.
if ( !DsoUtils::inDso( *it, DsoUtils::libNativeName(*iLib) ) ) {
cout << "WARNING: library [" << *iLib << "] requested factory "
<< "from another library ["
<< DsoUtils::dsoName(*it) << "]"
<< " ==> [" << ident << "] !!"
<< endl;
continue;
}
const string rtype = it->TypeOf().ReturnType().Name();
string type;
bool known = true;
if ( ident == "ApplicationMgr" ) type = "ApplicationMgr";
else if ( rtype == "IInterface*" ) type = "IInterface";
else if ( rtype == "IAlgorithm*" ) type = "Algorithm";
else if ( rtype == "IService*" ) type = "Service";
else if ( rtype == "IAlgTool*" ) type = "AlgTool";
else if ( rtype == "IAuditor*" ) type = "Auditor";
else if ( rtype == "IConverter*" ) type = "Converter";
else if ( rtype == "DataObject*" ) type = "DataObject";
else type = "Unknown", known = false;
string name = ident;
// handle possible problems with templated components
boost::trim(name);
cout << " - component: " << name << endl;
if ( type == "IInterface" ) {
continue;
}
if ( type == "Converter" || type == "DataObject" ) {
continue;
}
//if ( type == "ApplicationMgr" ) {
//}
if ( !known ) {
cout << "WARNING: Unknown (return) type [" << rtype << "] !!\n"
<< "WARNING: component [" << ident << "] is skipped !"
<< endl;
allGood = false;
continue;
}
string cname = "DefaultName";
vector<void*> args;
args.reserve( 3 );
if ( type == "AlgTool" ) {
args.resize( 3 );
args[0] = &cname;
args[1] = &type;
args[2] = dummySvc;
}
else {
args.resize( 2 );
args[0] = &cname;
args[1] = svcLoc;
}
IProperty* prop = 0;
try {
if ( type == "Algorithm" ) {
prop = makeInstance<IAlgorithm>(*it,args);
}
else if ( type == "Service") {
prop = makeInstance<IService>(*it,args);
}
else if ( type == "AlgTool") {
prop = makeInstance<IAlgTool>(*it,args);
}
else if ( type == "Auditor") {
prop = makeInstance<IAuditor>(*it,args);
}
else if ( type == "ApplicationMgr") {
//svcLoc->queryInterface(IProperty::interfaceID(), pp_cast<void>(&prop));
svcLoc->queryInterface(IProperty::interfaceID(), (void**)(&prop));
}
else {
prop = makeInstance<IInterface>(*it,args);
}
}
catch ( exception& e ) {
cout << "ERROR: Error instantiating " << name
<< " from " << *iLib << endl;
cout << "ERROR: Got exception: " << e.what() << endl;
allGood = false;
continue;
}
catch ( ... ) {
cout << "ERROR: Error instantiating " << name
<< " from " << *iLib << endl;
allGood = false;
continue;
}
if( prop ) {
if (genComponent( *iLib, name, type, prop->getProperties() )) {
allGood = false;
}
prop->release();
} else {
cout << "ERROR: could not cast IInterface* object to an IProperty* !\n"
<< "ERROR: return type from PluginSvc is [" << rtype << "]...\n"
<< "ERROR: NO Configurable will be generated for ["
<< name << "] !"
<< endl;
allGood = false;
}
} //> end loop over factories
const std::string pyName = ( fs::path(m_outputDirName) /
fs::path(*iLib+"Conf.py") ).string();
const std::string dbName = ( fs::path(m_outputDirName) /
fs::path(*iLib+"_confDb.py") ).string();
std::fstream py( pyName.c_str(),
std::ios_base::out|std::ios_base::trunc );
std::fstream db( dbName.c_str(),
std::ios_base::out|std::ios_base::trunc );
genHeader ( py, db );
genBody ( py, db );
genTrailer( py, db );
} //> end loop over libraries
dummySvc->release();
dummySvc = 0;
return allGood ? EXIT_SUCCESS : EXIT_FAILURE;
}
| void configGenerator::genHeader | ( | std::ostream & | pyOut, |
| std::ostream & | dbOut | ||
| ) | [private] |
Definition at line 695 of file genconf.cpp.
{
// python file part
std::string now = Gaudi::Time::current().format(true);
py << "#" << now //<< "\n"
<< "\"\"\"Automatically generated. DO NOT EDIT please\"\"\"\n";
if ( m_importGaudiHandles ) {
py << "from GaudiKernel.GaudiHandles import *\n";
}
genImport(py,boost::format("from %1%.Configurable import *"));
// db file part
db << "## -*- python -*- \n"
<< "# db file automatically generated by genconf on: "
<< now; // << "\n";
db << "## insulates outside world against anything bad that could happen\n"
<< "## also prevents global scope pollution\n"
<< "def _fillCfgDb():\n";
genImport(db,boost::format("from %1%.ConfigurableDb import CfgDb"),py_tab);
db << "\n"
<< py_tab << "# get a handle on the repository of Configurables\n"
<< py_tab << "cfgDb = CfgDb()\n"
<< "\n"
<< py_tab << "# populate the repository with informations on Configurables \n"
<< "\n"
<< flush;
}
| void configGenerator::genImport | ( | std::ostream & | s, |
| const boost::format & | frmt, | ||
| std::string | indent = "" |
||
| ) | [private] |
Definition at line 659 of file genconf.cpp.
{
std::string::size_type pos = 0, nxtpos = 0;
std::string mod;
while ( std::string::npos != pos ){
// find end of module name
nxtpos = m_configurable["Module"].find_first_of(',',pos);
// Prepare import string
mod = m_configurable["Module"].substr(pos,nxtpos-pos);
std::ostringstream import;
import << boost::format(frmt) % mod;
// append a normal import or a try/except enclosed one depending
// on availability of a fall-back module (next in the list)
if ( std::string::npos == nxtpos ) {
// last possible module
s << indent << import.str() << "\n" << flush;
pos = std::string::npos;
} else {
// we have a fallback for this
s << indent << "try:\n"
<< indent << py_tab << import.str() << "\n"
<< indent << "except ImportError:\n"
<< flush;
pos = nxtpos+1;
}
// increase indentation level for next iteration
indent += py_tab;
}
}
| void configGenerator::genTrailer | ( | std::ostream & | pyOut, |
| std::ostream & | dbOut | ||
| ) | [private] |
Definition at line 727 of file genconf.cpp.
{
// db file part
db << py_tab << "return #_fillCfgDb\n"
<< "# fill cfgDb at module import...\n"
<< "try:\n"
<< py_tab << "_fillCfgDb()\n"
<< py_tab << "#house cleaning...\n"
<< py_tab << "del _fillCfgDb\n"
<< "except Exception,err:\n"
<< py_tab << "print \"Py:ConfigurableDb ERROR Problem with [%s] content!"
<< "\" % __name__\n"
<< py_tab << "print \"Py:ConfigurableDb ERROR\",err\n"
<< py_tab << "print \"Py:ConfigurableDb ERROR ==> culprit is package ["
<< m_pkgName << "] !\"\n"
<< std::flush;
}
| void configGenerator::pythonizeName | ( | string & | name ) | [private] |
| void configGenerator::pythonizeValue | ( | const Property * | prop, |
| string & | pvalue, | ||
| string & | ptype | ||
| ) | [private] |
handle the "marshalling" of Properties
Definition at line 841 of file genconf.cpp.
{
const std::string cvalue = p->toString();
const type_info& ti = *p->type_info();
if ( ti == typeid(bool) ) {
pvalue = ( cvalue == "0" || cvalue == "False" || cvalue == "false" )
? "False"
: "True";
ptype = "bool";
}
else if ( ti == typeid(char) || ti == typeid(signed char)
|| ti == typeid(unsigned char) ||
ti == typeid(short) || ti == typeid(unsigned short) ||
ti == typeid(int) || ti == typeid(unsigned int) ||
ti == typeid(long) || ti == typeid(unsigned long) ) {
pvalue = cvalue;
ptype = "int";
}
else if ( ti == typeid(long long) || ti == typeid(unsigned long long) ) {
pvalue = cvalue + "L";
ptype = "long";
}
else if ( ti == typeid(float) || ti == typeid(double) ) {
// forces python to handle this as a float: put a dot in there...
pvalue = boost::to_lower_copy(cvalue);
if ( pvalue == "nan" ) {
pvalue = "float('nan')";
std::cout << "WARNING: default value for ["
<< p->name() << "] is NaN !!"
<< std::endl;
} else if ( std::string::npos == pvalue.find(".") &&
std::string::npos == pvalue.find("e") ) {
pvalue = cvalue + ".0";
}
ptype = "float";
}
else if ( ti == typeid(string) ) {
pvalue = "'"+cvalue+"'";
ptype = "str";
}
else if ( ti == typeid(GaudiHandleBase) ) {
m_importGaudiHandles = true;
const GaudiHandleProperty& hdl
= dynamic_cast<const GaudiHandleProperty&>(*p);
const GaudiHandleBase& base = hdl.value();
pvalue = base.pythonRepr();
ptype = "GaudiHandle";
}
else if ( ti == typeid(GaudiHandleArrayBase) ) {
m_importGaudiHandles = true;
const GaudiHandleArrayProperty& hdl
= dynamic_cast<const GaudiHandleArrayProperty&>(*p);
const GaudiHandleArrayBase& base = hdl.value();
pvalue = base.pythonRepr();
ptype = "GaudiHandleArray";
}
else {
std::ostringstream v_str;
v_str.setf(std::ios::fixed); // to correctly display floats
p->toStream(v_str);
pvalue = v_str.str();
ptype = "list";
}
}
| void configGenerator::setConfigurableAlgorithm | ( | const std::string & | cfgAlgorithm ) | [inline] |
customize the configurable base class for Algorithm component
Definition at line 150 of file genconf.cpp.
{
m_configurable[ "Algorithm" ] = cfgAlgorithm;
}
| void configGenerator::setConfigurableAlgTool | ( | const std::string & | cfgAlgTool ) | [inline] |
customize the configurable base class for AlgTool component
Definition at line 156 of file genconf.cpp.
{
m_configurable[ "AlgTool" ] = cfgAlgTool;
}
| void configGenerator::setConfigurableAuditor | ( | const std::string & | cfgAuditor ) | [inline] |
customize the configurable base class for AlgTool component
Definition at line 162 of file genconf.cpp.
{
m_configurable[ "Auditor" ] = cfgAuditor;
}
| void configGenerator::setConfigurableDefaultName | ( | const std::string & | defaultName ) | [inline] |
customize the default name for configurable instances
Definition at line 144 of file genconf.cpp.
{
m_configurable[ "DefaultName" ] = defaultName;
}
| void configGenerator::setConfigurableModule | ( | const std::string & | moduleName ) | [inline] |
customize the Module name where configurable base classes are defined
Definition at line 138 of file genconf.cpp.
{
m_configurable[ "Module" ] = moduleName;
}
| void configGenerator::setConfigurableService | ( | const std::string & | cfgService ) | [inline] |
customize the configurable base class for Service component
Definition at line 168 of file genconf.cpp.
{
m_configurable[ "Service" ] = cfgService;
m_configurable[ "ApplicationMgr" ] = cfgService;
}
Configurable customization.
Contains customization for:
Definition at line 118 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 111 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 105 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 98 of file genconf.cpp.
string configGenerator::m_pkgName [private] |
name of the package we are processing
Definition at line 94 of file genconf.cpp.
stringstream configGenerator::m_pyBuf [private] |
buffer of auto-generated configurables
Definition at line 101 of file genconf.cpp.