Gaudi Framework, version v24r2

Home   Generated: Wed Dec 4 2013
 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:
Collaboration graph
[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_dbBuf ( ),
{}

Member Function Documentation

void configGenerator::genBody ( std::ostream pyOut,
std::ostream dbOut 
)
inlineprivate

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 760 of file genconf.cpp.

{
string cname = componentName;
pythonizeName(cname);
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 ) {
<< "'" << iProp->first << "' : "
<< "\"\"\" " << iProp->second << " \"\"\",\n";
}
m_pyBuf << " }\n";
<< " 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
<< 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:

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 448 of file genconf.cpp.

{
//--- Disable checking StatusCode -------------------------------------------
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;
}
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_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 ----------------------------------------------
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";
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::fstream db( dbName.c_str(),
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 706 of file genconf.cpp.

{
// python file part
py << "#" << now //<< "\n"
<< "\"\"\"Automatically generated. DO NOT EDIT please\"\"\"\n";
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 670 of file genconf.cpp.

{
std::string::size_type pos = 0, nxtpos = 0;
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);
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;
} 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 738 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"
}
void configGenerator::pythonizeName ( string name)
private

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

Definition at line 841 of file genconf.cpp.

{
static string in("<>&*,: ().");
static string out("__rp__s___");
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 852 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 !!"
} 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) ) {
= dynamic_cast<const GaudiHandleProperty&>(*p);
const GaudiHandleBase& base = hdl.value();
pvalue = base.pythonRepr();
ptype = "GaudiHandle";
}
else if ( ti == typeid(GaudiHandleArrayBase) ) {
= dynamic_cast<const GaudiHandleArrayProperty&>(*p);
const GaudiHandleArrayBase& base = hdl.value();
pvalue = base.pythonRepr();
ptype = "GaudiHandleArray";
}
else {
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:

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
staticprivate

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:
Generated at Wed Dec 4 2013 14:33:14 for Gaudi Framework, version v24r2 by Doxygen version 1.8.2 written by Dimitri van Heesch, © 1997-2004