| # Gaudi Framework, version v25r0 |

Home |  | Generated: Mon Feb 17 2014

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- Class List
- Class Index
- Class Hierarchy
- Class Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
Public Member Functions | Private Member Functions | Private Attributes | Static Private Attributes | List of all members
configGenerator Class Reference
Collaboration diagram for configGenerator:
[legend]

## Public Member Functions
| configGenerator (const string &pkgName, const string &outputDirName)
int | genConfig (const Strings_t &modules, const string &userModule)
| 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_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.

## Static Private Attributes
string | m_pkgName
| name of the package we are processing

## Detailed Description

Definition at line 91 of file genconf.cpp.

## Constructor & Destructor Documentation

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 ( )
{}

## Member Function Documentation

void configGenerator::genBody | ( | std::ostream & | pyOut,
|  | std::ostream & | dbOut
| ) |  |
| inline private

Definition at line 181 of file genconf.cpp.

{
pyOut << m_pyBuf.str() << flush;
dbOut << m_dbBuf.str() << flush;
}

int configGenerator::genComponent | ( | const std::string & | libName,
|  | const std::string & | componentName,
|  | const std::string & | componentType,
|  | const vector< Property * > & | properties
| ) |  |
| private

Definition at line 715 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,
|  | const string & | userModule
| ) |  |

main entry point of this class:

- iterate over all the modules (ie: library names)
- for each module extract component informations
- eventually generate the header/body/trailer python file and "Db" file

not enough information... skip it

no Properties, so don't bother create Configurables...

write-out files for this library

Definition at line 429 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 --------------------------------------
using Gaudi::PluginService::Details::Registry;
Registry& registry = Registry::instance();
std::set<std::string> bkgNames = registry.loadedFactories();
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("");
//--- Load component library ----------------------------------------------
System::ImageHandle handle;
unsigned long err = System::loadDynamicLib( *iLib, &handle );
if ( err != 1 ) {
cout << "ERROR: " << System::getLastErrorString() << endl;
allGood = false;
continue;
}
std::set<std::string> factories = registry.loadedFactories();
for ( std::set<std::string>::iterator it = factories.begin();
it != factories.end(); ++it ) {
const string ident = *it;
if ( bkgNames.find(ident) != bkgNames.end() ) {
if ( Gaudi::PluginService::Details::logger().level() <= 1 ) {
cout << "\t==> skipping [" << ident << "]..." << endl;
}
continue;
}
const Registry::FactoryInfo info = registry.getInfo(*it);
const string rtype = info.rtype;
// do not generate configurables for the Reflex-compatible aliases
if (info.properties.find("ReflexName") != info.properties.end())
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).
if ( !DsoUtils::inDso( info.ptr, DsoUtils::libNativeName(*iLib) ) ) {
cout << "WARNING: library [" << *iLib << "] exposes factory ["
<< ident << "] which is declared in ["
<< DsoUtils::dsoName(info.ptr) << "] !!" << endl;
continue;
}
string type;
bool known = true;
if ( ident == "ApplicationMgr" ) type = "ApplicationMgr";
else if ( rtype == typeid(IInterface*).name() ) type = "IInterface";
else if ( rtype == typeid(IAlgorithm*).name() ) type = "Algorithm";
else if ( rtype == typeid(IService* ).name() ) type = "Service";
else if ( rtype == typeid(IAlgTool* ).name() ) type = "AlgTool";
else if ( rtype == typeid(IAuditor* ).name() ) type = "Auditor";
else if ( rtype == typeid(IConverter*).name() ) type = "Converter";
else if ( rtype == typeid(DataObject*).name() ) type = "DataObject";
else type = "Unknown", known = false;
string name = ident;
// handle possible problems with templated components
boost::trim(name);
if ( type == "IInterface" ) {
continue;
}
if ( type == "Converter" || type == "DataObject" ) {
continue;
}
if ( !known ) {
cout << "WARNING: Unknown (return) type [" << rtype << "] !!\n"
<< "WARNING: component [" << ident << "] is skipped !"
<< endl;
allGood = false;
continue;
}
cout << " - component: " << info.className << " (";
if (info.className != name)
cout << name << ": ";
cout << type << ")" << endl;
string cname = "DefaultName";
SmartIF<IProperty> prop;
try {
if ( type == "Algorithm" ) {
prop = SmartIF<IAlgorithm>(Algorithm::Factory::create(ident, cname, svcLoc));
}
else if ( type == "Service") {
prop = SmartIF<IService>(Service::Factory::create(ident, cname, svcLoc));
}
else if ( type == "AlgTool") {
prop = SmartIF<IAlgTool>(AlgTool::Factory::create(ident, cname, type, dummySvc));
// FIXME: AlgTool base class increase artificially by 1 the refcount.
prop->release();
}
else if ( type == "Auditor") {
prop = SmartIF<IAuditor>(Auditor::Factory::create(ident, cname, svcLoc));
}
else if ( type == "ApplicationMgr") {
prop = SmartIF<ISvcLocator>(svcLoc);
}
else {
continue; // unknown
}
}
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.reset();
} 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 );
if (!userModule.empty())
py << "from " << userModule << " import *" <<endl;
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 661 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 625 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 693 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

Translates a valid C++ typename into a valid python one.

Definition at line 796 of file genconf.cpp.

{
static string in("<>&*,: ().");
static string out("__rp__s___");
boost::algorithm::replace_all(name, ", ", ",");
for ( string::iterator i = name.begin(); i != name.end(); ++i ) {
if ( in.find(*i) != string::npos ) *i = out[in.find(*i)];
}
}

void configGenerator::pythonizeValue | ( | const Property * | prop,
|  | string & | pvalue,
|  | string & | ptype
| ) |  |
| private

handle the "marshalling" of Properties

Definition at line 808 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;
}

## Member Data Documentation

GaudiUtils::HashMap<std::string, std::string> configGenerator::m_configurable
| private

Configurable customization.

Contains customization for:

- Name of the module where configurable base classes are defined
- Name of the configurable base class for the Algorithm component
- Name of the configurable base class for the AlgTool component
- Name of the configurable base class for the Service component

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
| static 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.

The documentation for this class was generated from the following file:

- /afs/cern.ch/sw/Gaudi/releases/GAUDI/GAUDI_v25r0/GaudiKernel/src/Util/genconf.cpp