Gaudi Framework, version v22r0

Home   Generated: 9 Feb 2011

configGenerator Class Reference

Collaboration diagram for configGenerator:
Collaboration graph
[legend]

List of all members.

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.

Detailed Description

Definition at line 82 of file genconf.cpp.


Constructor & Destructor Documentation

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

Definition at line 112 of file genconf.cpp.

00114                                                  :
00115     m_pkgName           ( pkgName ),
00116     m_outputDirName     ( outputDirName ),
00117     m_pyBuf             ( ),
00118     m_importGaudiHandles( false ),
00119     m_dbBuf             ( ),
00120     m_configurable      ( )
  {}


Member Function Documentation

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

Definition at line 172 of file genconf.cpp.

00173                                     {
00174     pyOut << m_pyBuf.str() << flush;
00175     dbOut << m_dbBuf.str() << flush;
00176   }

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

Definition at line 742 of file genconf.cpp.

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

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

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

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

Definition at line 688 of file genconf.cpp.

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

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

Definition at line 652 of file genconf.cpp.

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

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

Definition at line 721 of file genconf.cpp.

00724 {
00725   // db file part
00726   db << py_tab << "return #_fillCfgDb\n"
00727      << "# fill cfgDb at module import...\n"
00728      << "try:\n"
00729      << py_tab << "_fillCfgDb()\n"
00730      << py_tab << "#house cleaning...\n"
00731      << py_tab << "del _fillCfgDb\n"
00732      << "except Exception,err:\n"
00733      << py_tab << "print \"Py:ConfigurableDb   ERROR Problem with [%s] content!"
00734                << "\" % __name__\n"
00735      << py_tab << "print \"Py:ConfigurableDb   ERROR\",err\n"
00736      << py_tab << "print \"Py:ConfigurableDb   ERROR   ==> culprit is package ["
00737                << m_pkgName << "] !\"\n"
00738      << std::flush;
00739 }

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

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

Definition at line 810 of file genconf.cpp.

00812 {
00813   static string  in("<>&*,: ().");
00814   static string out("__rp__s___");
00815   for ( string::iterator i = name.begin(); i != name.end(); ++i ) {
00816     if ( in.find(*i) != string::npos ) *i = out[in.find(*i)];
00817   }
00818 }

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

handle the "marshalling" of Properties

Definition at line 821 of file genconf.cpp.

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

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

customize the configurable base class for Algorithm component

Definition at line 141 of file genconf.cpp.

00142   {
00143     m_configurable[ "Algorithm" ] = cfgAlgorithm;
00144   }

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

customize the configurable base class for AlgTool component

Definition at line 147 of file genconf.cpp.

00148   {
00149     m_configurable[ "AlgTool" ] = cfgAlgTool;
00150   }

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

customize the configurable base class for AlgTool component

Definition at line 153 of file genconf.cpp.

00154   {
00155     m_configurable[ "Auditor" ] = cfgAuditor;
00156   }

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

customize the default name for configurable instances

Definition at line 135 of file genconf.cpp.

00136   {
00137     m_configurable[ "DefaultName" ] = defaultName;
00138   }

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

customize the Module name where configurable base classes are defined

Definition at line 129 of file genconf.cpp.

00130   {
00131     m_configurable[ "Module" ] = moduleName;
00132   }

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

customize the configurable base class for Service component

Definition at line 159 of file genconf.cpp.

00160   {
00161     m_configurable[ "Service" ] = cfgService;
00162     m_configurable[ "ApplicationMgr" ] = cfgService;
00163   }


Member Data Documentation

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

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

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

Definition at line 89 of file genconf.cpp.

string configGenerator::m_pkgName [private]

name of the package we are processing

Definition at line 85 of file genconf.cpp.

buffer of auto-generated configurables

Definition at line 92 of file genconf.cpp.


The documentation for this class was generated from the following file:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines

Generated at Wed Feb 9 16:30:23 2011 for Gaudi Framework, version v22r0 by Doxygen version 1.6.2 written by Dimitri van Heesch, © 1997-2004