Gaudi Framework, version v20r4

Generated: 8 Jan 2009

configGenerator Class Reference

Collaboration diagram for configGenerator:

Collaboration graph
[legend]

List of all members.


Detailed Description

Definition at line 72 of file genconf.cpp.


Public Member Functions

 configGenerator (const string &pkgName, const string &outputDirName)
int genConfig (const Strings_t &modules)
 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

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.

Constructor & Destructor Documentation

configGenerator::configGenerator ( const string &  pkgName,
const string &  outputDirName 
) [inline]

Definition at line 102 of file genconf.cpp.

00103                                                  : 
00104     m_pkgName           ( pkgName ),
00105     m_outputDirName     ( outputDirName ),
00106     m_pyBuf             ( ),
00107     m_importGaudiHandles( false ),
00108     m_dbBuf             ( ),
00109     m_configurable      ( )
00110   {}


Member Function Documentation

int configGenerator::genConfig ( const Strings_t modules  ) 

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

: no Configurable for this component. yet... continue;

write-out files for this library

Definition at line 424 of file genconf.cpp.

00426 {
00427   //--- Disable checking StatusCode -------------------------------------------
00428   StatusCode::disableChecking();
00429   
00430   const Strings_t::const_iterator endLib = libs.end();
00431   
00432   const std::string gaudiSvc = "GaudiSvc";
00433   const bool isGaudiSvc = ( std::find( libs.begin(), endLib, gaudiSvc ) != endLib );
00434   
00435   //--- Instantiate ApplicationMgr --------------------------------------------
00436   if ( !isGaudiSvc && createAppMgr() ) {
00437     cout << "ERROR: ApplicationMgr can not be created. Check environment" << endl;
00438     return EXIT_FAILURE;
00439   }
00440   
00441   //--- Iterate over component factories --------------------------------------
00442   Scope factories = Scope::ByName(PLUGINSVC_FACTORY_NS);
00443   if ( !factories ) {
00444     cout << "ERROR: No PluginSvc factory namespace could be found" << endl;
00445     return EXIT_FAILURE;
00446   }
00447   
00448   ISvcLocator* svcLoc = Gaudi::svcLocator();
00449   IService*    dummySvc = new Service( "DummySvc", svcLoc );
00450   dummySvc->addRef();
00451 
00452   bool allGood = true;
00453 
00454   // iterate over all the requested libraries
00455   for ( Strings_t::const_iterator iLib=libs.begin(); iLib != endLib; ++iLib ) {
00456     
00457     std::cout << ":::: processing library: " << *iLib << "..." << std::endl;
00458     
00459     // reset state
00460     m_importGaudiHandles = false;
00461     m_pyBuf.str("");
00462     m_dbBuf.str("");
00463 
00464     // Scan the pluginSvc namespace and store the "background" of already
00465     // alived components, so we can extract our signal later on
00466     set<string> bkgNames;
00467     if ( !isGaudiSvc ) {
00468       for ( Member_Iterator it = factories.FunctionMember_Begin(); 
00469             it != factories.FunctionMember_End(); ++it ) {
00470         string ident = getId(*it);
00471         if ( PluginService::Debug() > 0 ) {
00472           cout << "::: " << ident << endl;
00473         }
00474         bkgNames.insert( ident );
00475       }
00476     }
00477     const set<string>::const_iterator bkgNamesEnd = bkgNames.end();
00478     
00479     //--- Load component library ----------------------------------------------
00480     System::ImageHandle handle;
00481     unsigned long err = System::loadDynamicLib( *iLib, &handle );
00482     if ( err != 1 ) {
00483       cout << "ERROR: " << System::getLastErrorString() << endl;
00484       allGood = false;
00485       continue;
00486     }
00487     
00488     for ( Member_Iterator it = factories.FunctionMember_Begin(); 
00489           it != factories.FunctionMember_End(); 
00490           ++it ) {
00491       const string ident = getId(*it);
00492       if ( bkgNames.find(ident) != bkgNamesEnd ) {
00493         if ( PluginService::Debug() > 0 ) {
00494           cout << "\t==> skipping [" << ident << "]..." << endl;
00495         }
00496         continue;
00497       }
00498       
00499       // Atlas contributed code (patch #1247)
00500       // Skip the generation of configurables if the component does not come
00501       // from the same library we are processing (i.e. we found a symbol that
00502       // is coming from a library loaded by the linker).
00503       // Windows implementation is empty.
00504       if ( !DsoUtils::inDso( *it, DsoUtils::libNativeName(*iLib) ) ) {
00505         cout << "WARNING: library [" << *iLib << "] requested factory "
00506         << "from another library ["
00507         << DsoUtils::dsoName(*it) << "]"
00508         << " ==> [" << ident << "] !!"
00509         << endl;
00510         continue;
00511       }
00512 
00513       const string rtype = it->TypeOf().ReturnType().Name();
00514       string type;
00515       bool known = true;
00516       if      ( ident == "ApplicationMgr" ) type = "ApplicationMgr";
00517       else if ( rtype == "IInterface*" )    type = "IInterface";
00518       else if ( rtype == "IAlgorithm*" )    type = "Algorithm";
00519       else if ( rtype == "IService*" )      type = "Service";
00520       else if ( rtype == "IAlgTool*" )      type = "AlgTool";
00521       else if ( rtype == "IAuditor*" )      type = "Auditor";
00522       else if ( rtype == "IConverter*" )    type = "Converter";
00523       else if ( rtype == "DataObject*" )    type = "DataObject";
00524       else                                  type = "Unknown", known = false;
00525       string name = ident;
00526       // handle possible problems with templated components
00527       boost::trim(name);
00528 
00529       cout << " - component: " << name << endl;
00530       
00531       if ( type == "IInterface" ) {
00534         continue;
00535       }
00536       
00537       if ( type == "Converter" || type == "DataObject" ) {
00539         continue;
00540       }
00541       
00542       //if ( type == "ApplicationMgr" ) {
00545       //}
00546 
00547       if ( !known ) {
00548         cout << "WARNING: Unknown (return) type [" << rtype << "] !!\n"
00549              << "WARNING: component [" << ident << "] is skipped !"
00550              << endl;
00551         allGood = false;
00552         continue;
00553       }
00554       
00555       string cname = "DefaultName";
00556       vector<void*>  args; 
00557       args.reserve( 3 );
00558       if ( type == "AlgTool" ) {
00559         args.resize( 3 );
00560         args[0] = &cname;
00561         args[1] = &type;
00562         args[2] = dummySvc;
00563       }
00564       else {
00565         args.resize( 2 );
00566         args[0] = &cname;
00567         args[1] = svcLoc;
00568       }
00569       IProperty* prop = 0;
00570       try {
00571         if ( type == "Algorithm" ) {
00572           prop = makeInstance<IAlgorithm>(*it,args);
00573         }
00574         else if ( type == "Service") {
00575           prop = makeInstance<IService>(*it,args);
00576         }
00577         else if ( type == "AlgTool") {
00578           prop = makeInstance<IAlgTool>(*it,args);
00579         }
00580         else if ( type == "Auditor") {
00581           prop = makeInstance<IAuditor>(*it,args);
00582         }
00583         else if ( type == "ApplicationMgr") {
00584           //svcLoc->queryInterface(IProperty::interfaceID(), pp_cast<void>(&prop));
00585           svcLoc->queryInterface(IProperty::interfaceID(), (void**)(&prop));
00586         }
00587         else {
00588           prop = makeInstance<IInterface>(*it,args);
00589         }
00590       }
00591       catch ( exception& e ) {
00592         cout << "ERROR: Error instantiating " << name 
00593              << " from " << *iLib << endl;
00594         cout << "ERROR: Got exception: " << e.what() << endl;
00595         allGood = false;
00596         continue;
00597       }
00598       catch ( ... ) {
00599         cout << "ERROR: Error instantiating " << name 
00600              << " from " << *iLib << endl;
00601         allGood = false;
00602         continue;
00603       }
00604       if( prop ) {
00605         genComponent( *iLib, name, type, prop->getProperties() );
00606         prop->release();
00607       } else {
00608         cout << "ERROR: could not cast IInterface* object to an IProperty* !\n"
00609              << "ERROR: return type from PluginSvc is [" << rtype << "]...\n"
00610              << "ERROR: NO Configurable will be generated for [" 
00611              << name << "] !"
00612              << endl;
00613         allGood = false;
00614       }
00615     } //> end loop over factories
00616 
00620     const std::string pyName = ( fs::path(m_outputDirName) /
00621                   fs::path(*iLib+"Conf.py") ).string();
00622     const std::string dbName = ( fs::path(m_outputDirName) /
00623                   fs::path(*iLib+"_confDb.py") ).string();
00624 
00625     std::fstream py( pyName.c_str(),
00626               std::ios_base::out|std::ios_base::trunc );
00627     std::fstream db( dbName.c_str(),
00628               std::ios_base::out|std::ios_base::trunc );
00629     
00630     genHeader ( py, db );
00631     genBody   ( py, db );
00632     genTrailer( py, db );
00633     
00634   } //> end loop over libraries
00635   
00636   dummySvc->release();
00637   dummySvc = 0;
00638   
00639   return allGood ? EXIT_SUCCESS : EXIT_FAILURE;
00640 }

void configGenerator::setConfigurableModule ( const std::string &  moduleName  )  [inline]

customize the Module name where configurable base classes are defined

Definition at line 119 of file genconf.cpp.

00120   {
00121     m_configurable[ "Module" ] = moduleName;
00122   }

void configGenerator::setConfigurableDefaultName ( const std::string &  defaultName  )  [inline]

customize the default name for configurable instances

Definition at line 125 of file genconf.cpp.

00126   {
00127     m_configurable[ "DefaultName" ] = defaultName;
00128   }

void configGenerator::setConfigurableAlgorithm ( const std::string &  cfgAlgorithm  )  [inline]

customize the configurable base class for Algorithm component

Definition at line 131 of file genconf.cpp.

00132   {
00133     m_configurable[ "Algorithm" ] = cfgAlgorithm;
00134   }

void configGenerator::setConfigurableAlgTool ( const std::string &  cfgAlgTool  )  [inline]

customize the configurable base class for AlgTool component

Definition at line 137 of file genconf.cpp.

00138   {
00139     m_configurable[ "AlgTool" ] = cfgAlgTool;
00140   }

void configGenerator::setConfigurableAuditor ( const std::string &  cfgAuditor  )  [inline]

customize the configurable base class for AlgTool component

Definition at line 143 of file genconf.cpp.

00144   {
00145     m_configurable[ "Auditor" ] = cfgAuditor;
00146   }

void configGenerator::setConfigurableService ( const std::string &  cfgService  )  [inline]

customize the configurable base class for Service component

Definition at line 149 of file genconf.cpp.

00150   {
00151     m_configurable[ "Service" ] = cfgService;
00152     m_configurable[ "ApplicationMgr" ] = cfgService;
00153   }

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

Definition at line 732 of file genconf.cpp.

00737 {
00738   string cname = componentName;
00739   pythonizeName(cname);
00740     
00741   typedef GaudiUtils::HashMap<std::string, std::string> PropertyDoc_t;
00742   PropertyDoc_t propDoc;
00743   
00744   m_pyBuf << "\n";
00745   m_pyBuf << "class " << cname 
00746           << "( " << m_configurable[componentType] << " ) :" 
00747           << "\n";
00748   m_pyBuf << "  __slots__ = { \n";
00749   for ( vector<Property*>::const_iterator it = properties.begin() ; 
00750         it != properties.end(); ++it ) {
00751     const string pname  = (*it)->name();
00752     string pvalue, ptype;
00753     pythonizeValue( (*it), pvalue, ptype );
00754     m_pyBuf << "    '" << pname << "' : " << pvalue <<", # " << ptype << "\n";
00755     
00756     if ( (*it)->documentation() != "none" ) {
00757       propDoc[pname] = (*it)->documentation();
00758     }
00759     
00760   }
00761   m_pyBuf << "  }\n";
00762   m_pyBuf << "  _propertyDocDct = { \n";
00763   for ( PropertyDoc_t::const_iterator iProp = propDoc.begin();
00764         iProp != propDoc.end();
00765         ++iProp ) {
00766     m_pyBuf << std::setw(5)  
00767             << "'"       << iProp->first  << "' : "
00768             << "\"\"\" "  << iProp->second << " \"\"\",\n";
00769   }
00770   m_pyBuf << "  }\n";
00771   
00772   m_pyBuf 
00773     << "  def __init__(self, name = " << m_configurable["DefaultName"]
00774                                       << ", **kwargs):\n"
00775     << "      super(" << cname << ", self).__init__(name)\n"
00776     << "      for n,v in kwargs.items():\n"
00777     << "         setattr(self, n, v)\n"
00778     << "  def getDlls( self ):\n"
00779     << "      return '" << libName << "'\n"
00780     << "  def getType( self ):\n"
00781     << "      return '" << componentName  << "'\n"
00782     << "  pass # class " << cname << "\n"
00783     << flush;
00784   
00785   // name of the auto-generated module
00786   const string pyName = ( fs::path(m_outputDirName) /
00787                           fs::path(libName+"Conf.py") ).string();
00788   const string modName = fs::basename( fs::path( pyName ).leaf() );
00789   
00790   // now the db part
00791   m_dbBuf 
00792     << py_tab << "cfgDb.add( configurable = '" << cname << "',\n"
00793     << py_tab << "           package = '" << m_pkgName << "',\n"
00794     << py_tab << "           module  = '" << m_pkgName << "." << modName << "',\n"
00795     << py_tab << "           lib     = '" << libName << "' )\n"
00796     << flush;
00797 
00798 }

void configGenerator::genImport ( std::ostream &  s,
const boost::format &  frmt,
std::string  indent = "" 
) [private]

Definition at line 642 of file genconf.cpp.

00644                                                        {
00645   
00646   std::string::size_type pos = 0, nxtpos = 0;
00647   std::string mod;
00648   
00649   while ( std::string::npos != pos ){
00650     // find end of module name
00651     nxtpos = m_configurable["Module"].find_first_of(',',pos);
00652     
00653     // Prepare import string
00654     mod = m_configurable["Module"].substr(pos,nxtpos-pos);
00655     std::ostringstream import;
00656     import << boost::format(frmt) % mod;
00657     
00658     // append a normal import or a try/excpet enclosed one depending
00659     // on availability of a fall-back bodule (next in the list)
00660     if ( std::string::npos == nxtpos ) {
00661       // last possible module
00662       s << indent << import.str() << "\n" << flush;
00663       pos = std::string::npos;
00664     } else {
00665       // we have a fallback for this
00666       s << indent << "try:\n"
00667         << indent << py_tab << import.str() << "\n"
00668         << indent << "except ImportError:\n"
00669         << flush;
00670       pos = nxtpos+1;
00671     }
00672     // increase indentation level for next iteration
00673     indent += py_tab;
00674   }
00675 }

void configGenerator::genHeader ( std::ostream &  pyOut,
std::ostream &  dbOut 
) [private]

Definition at line 678 of file genconf.cpp.

00681 {
00682   // python file part
00683   time_t rawtime;
00684   time( &rawtime );
00685   py << "#" << ctime(&rawtime) //<< "\n"
00686      << "\"\"\"Automatically generated. DO NOT EDIT please\"\"\"\n";
00687   if ( m_importGaudiHandles ) {
00688     py << "from GaudiKernel.GaudiHandles import *\n";
00689   }
00690   
00691   genImport(py,boost::format("from %1%.Configurable import *"));
00692   
00693   // db file part
00694   db << "##  -*- python -*-  \n"
00695      << "# db file automatically generated by genconf on: " 
00696      << ctime(&rawtime); // << "\n";
00697   db << "## insulates outside world against anything bad that could happen\n"
00698      << "## also prevents global scope pollution\n"
00699      << "def _fillCfgDb():\n";
00700   genImport(db,boost::format("from %1%.ConfigurableDb import CfgDb"),py_tab);
00701   
00702   db << "\n"
00703      << py_tab << "# get a handle on the repository of Configurables\n"
00704      << py_tab << "cfgDb = CfgDb()\n"
00705      << "\n"
00706      << py_tab << "# populate the repository with informations on Configurables \n"
00707      << "\n"
00708      << flush;
00709 }

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

Definition at line 162 of file genconf.cpp.

00163                                     { 
00164     pyOut << m_pyBuf.str() << flush;
00165     dbOut << m_dbBuf.str() << flush;
00166   }

void configGenerator::genTrailer ( std::ostream &  pyOut,
std::ostream &  dbOut 
) [private]

Definition at line 711 of file genconf.cpp.

00714 {
00715   // db file part
00716   db << py_tab << "return #_fillCfgDb\n"
00717      << "# fill cfgDb at module import...\n"
00718      << "try:\n"
00719      << py_tab << "_fillCfgDb()\n"
00720      << py_tab << "#house cleaning...\n"
00721      << py_tab << "del _fillCfgDb\n"
00722      << "except Exception,err:\n"
00723      << py_tab << "print \"Py:ConfigurableDb   ERROR Problem with [%s] content!"
00724                << "\" % __name__\n"
00725      << py_tab << "print \"Py:ConfigurableDb   ERROR\",err\n"
00726      << py_tab << "print \"Py:ConfigurableDb   ERROR   ==> culprit is package ["
00727                << m_pkgName << "] !\"\n"
00728      << std::flush;
00729 }

void configGenerator::pythonizeValue ( const Property prop,
string &  pvalue,
string &  ptype 
) [private]

handle the "marshalling" of Properties

Definition at line 811 of file genconf.cpp.

00814 {
00815   const std::string cvalue = p->toString();
00816   const type_info& ti = *p->type_info();
00817   if ( ti == typeid(bool) ) {
00818     pvalue = ( cvalue == "0" || cvalue == "False" || cvalue == "false" )
00819            ? "False" 
00820            : "True";
00821     ptype  = "bool";
00822   }
00823   else if ( ti == typeid(char)  || ti == typeid(signed char)    
00824             || ti == typeid(unsigned char)  ||
00825             ti == typeid(short) || ti == typeid(unsigned short) ||
00826             ti == typeid(int)   || ti == typeid(unsigned int)   ||
00827             ti == typeid(long)  || ti == typeid(unsigned long) ) {
00828     pvalue = cvalue;
00829     ptype  = "int";
00830   }
00831   else if ( ti == typeid(long long) || ti == typeid(unsigned long long) ) {
00832     pvalue = cvalue + "L";
00833     ptype  = "long";
00834   }
00835   else if ( ti == typeid(float) || ti == typeid(double) ) {
00836     // forces python to handle this as a float: put a dot in there...
00837     pvalue = boost::to_lower_copy(cvalue);
00838     if ( pvalue == "nan" ) {
00839       pvalue = "float('nan')";
00840       std::cout << "WARNING: default value for ["
00841                 << p->name() << "] is NaN !!"
00842                 << std::endl;
00843     } else if ( std::string::npos == pvalue.find(".") &&
00844                 std::string::npos == pvalue.find("e")  ) {
00845       pvalue = cvalue + ".0";
00846     }
00847     ptype  = "float";
00848   }
00849   else if ( ti == typeid(string) ) {
00850     
00851     pvalue = "'"+cvalue+"'";
00852     ptype  = "str";
00853   }
00854   else if ( ti == typeid(GaudiHandleBase) ) {
00855     m_importGaudiHandles = true;
00856     const GaudiHandleProperty& hdl 
00857       = dynamic_cast<const GaudiHandleProperty&>(*p);
00858     const GaudiHandleBase&     base = hdl.value();
00859     
00860     pvalue = base.pythonRepr();
00861     ptype  = "GaudiHandle";
00862   }
00863   else if ( ti == typeid(GaudiHandleArrayBase) ) {
00864     m_importGaudiHandles = true;
00865     const GaudiHandleArrayProperty& hdl 
00866       = dynamic_cast<const GaudiHandleArrayProperty&>(*p);
00867     const GaudiHandleArrayBase&     base = hdl.value();
00868     
00869     pvalue = base.pythonRepr();
00870     ptype  = "GaudiHandleArray";
00871   }
00872   else {
00873     pvalue = cvalue;
00874     ptype  = "list";
00875   }
00876 }

void configGenerator::pythonizeName ( string &  name  )  [private]

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

Definition at line 800 of file genconf.cpp.

00802 {
00803   static string  in("<>&*,: ().");
00804   static string out("__rp__s___");
00805   for ( string::iterator i = name.begin(); i != name.end(); ++i ) {
00806     if ( in.find(*i) != string::npos ) *i = out[in.find(*i)];
00807   }  
00808 }


Member Data Documentation

string configGenerator::m_pkgName [private]

name of the package we are processing

Definition at line 75 of file genconf.cpp.

absolute path to the directory where genconf will store auto-generated files (Configurables and ConfigurableDb)

Definition at line 79 of file genconf.cpp.

stringstream configGenerator::m_pyBuf [private]

buffer of auto-generated configurables

Definition at line 82 of file genconf.cpp.

switch to decide if the generated configurables need to import GaudiHandles (ie: if one of the components has a XyzHandle<T>)

Definition at line 86 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 92 of file genconf.cpp.

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


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

Generated at Thu Jan 8 17:50:48 2009 for Gaudi Framework, version v20r4 by Doxygen version 1.5.6 written by Dimitri van Heesch, © 1997-2004