Gaudi Framework, version v23r5

Home   Generated: Wed Nov 28 2012
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
genconf.cpp
Go to the documentation of this file.
1 #ifdef _WIN32
2 // Disable a warning in Boost program_options headers:
3 // inconsistent linkage in program_options/variables_map.hpp
4 #pragma warning ( disable : 4273 )
5 
6 // Avoid conflicts between windows and the message service.
7 #define NOMSG
8 #define NOGDI
9 #endif
10 
11 #ifdef __ICC
12 // disable icc warning #279: controlling expression is constant
13 // ... a lot of noise produced by the boost/filesystem/operations.hpp
14 #pragma warning(disable:279)
15 // Avoid icc remark #193: zero used for undefined preprocessing identifier "_MSC_VER"
16 #if !defined(_WIN32) && !defined(_MSC_VER)
17 #define _MSC_VER 0
18 #endif
19 #endif
20 
21 #include "boost/program_options.hpp"
22 // the hack for remark #193 is needed only for program_options and breaks regex.
23 #if defined(__ICC) && !defined(_WIN32) && (_MSC_VER == 0)
24 #undef _MSC_VER
25 #endif
26 
27 // Include files----------------------------------------------------------------
28 #include "boost/filesystem/operations.hpp"
29 #include "boost/filesystem/exception.hpp"
30 #include "boost/filesystem/convenience.hpp"
31 #include "boost/algorithm/string/split.hpp"
32 #include "boost/algorithm/string/classification.hpp"
33 #include "boost/algorithm/string/trim.hpp"
34 #include "boost/algorithm/string/case_conv.hpp"
35 #include "boost/format.hpp"
36 #include "boost/regex.hpp"
37 
38 #include "GaudiKernel/System.h"
40 #include "GaudiKernel/IProperty.h"
41 #include "GaudiKernel/IAppMgrUI.h"
42 #include "GaudiKernel/IAlgorithm.h"
43 #include "GaudiKernel/IAlgTool.h"
44 #include "GaudiKernel/IAuditor.h"
45 #include "GaudiKernel/IAppMgrUI.h"
46 #include "GaudiKernel/Service.h"
47 #include "GaudiKernel/Bootstrap.h"
48 #include "GaudiKernel/SmartIF.h"
49 #include "GaudiKernel/HashMap.h"
51 
52 #include "GaudiKernel/Time.h"
53 
54 #include "Reflex/PluginService.h"
55 #include "Reflex/Reflex.h"
56 #include "Reflex/SharedLibrary.h"
57 
58 #include "RVersion.h"
59 
60 #include <algorithm>
61 #include <iostream>
62 #include <fstream>
63 #include <sstream>
64 #include <exception>
65 #include <set>
66 #include <vector>
67 
68 
69 #include "DsoUtils.h"
70 
71 
72 
73 namespace po = boost::program_options;
74 namespace fs = boost::filesystem;
75 
76 using namespace std;
77 using namespace ROOT::Reflex;
78 
79 // useful typedefs
82 
83 namespace {
84  const std::string py_tab = " ";
85 
88  const boost::regex pythonIdentifier("^[a-zA-Z_][a-zA-Z0-9_]*$");
89 }
90 
92 {
94  string m_pkgName;
95 
99 
102 
106 
112 
119 
120 public:
121  configGenerator( const string& pkgName,
122  const string& outputDirName ) :
123  m_pkgName ( pkgName ),
124  m_outputDirName ( outputDirName ),
125  m_pyBuf ( ),
126  m_importGaudiHandles( false ),
127  m_dbBuf ( ),
128  m_configurable ( )
129  {}
130 
135  int genConfig( const Strings_t& modules );
136 
138  void setConfigurableModule( const std::string& moduleName )
139  {
140  m_configurable[ "Module" ] = moduleName;
141  }
142 
144  void setConfigurableDefaultName( const std::string& defaultName )
145  {
146  m_configurable[ "DefaultName" ] = defaultName;
147  }
148 
150  void setConfigurableAlgorithm( const std::string& cfgAlgorithm )
151  {
152  m_configurable[ "Algorithm" ] = cfgAlgorithm;
153  }
154 
156  void setConfigurableAlgTool( const std::string& cfgAlgTool )
157  {
158  m_configurable[ "AlgTool" ] = cfgAlgTool;
159  }
160 
162  void setConfigurableAuditor( const std::string& cfgAuditor )
163  {
164  m_configurable[ "Auditor" ] = cfgAuditor;
165  }
166 
168  void setConfigurableService( const std::string& cfgService )
169  {
170  m_configurable[ "Service" ] = cfgService;
171  m_configurable[ "ApplicationMgr" ] = cfgService;
172  }
173 
174 private:
175  int genComponent( const std::string& libName,
176  const std::string& componentName,
177  const std::string& componentType,
178  const vector<Property*>& properties );
179  void genImport( std::ostream& s, const boost::format& frmt,std::string indent);
180  void genHeader( std::ostream& pyOut, std::ostream& dbOut );
181  void genBody( std::ostream& pyOut,
182  std::ostream& dbOut ) {
183  pyOut << m_pyBuf.str() << flush;
184  dbOut << m_dbBuf.str() << flush;
185  }
186  void genTrailer( std::ostream& pyOut,
187  std::ostream& dbOut );
188 
190  void pythonizeValue( const Property* prop,
191  string& pvalue,
192  string& ptype );
193 
195  void pythonizeName( string& name );
196 };
197 
198 int createAppMgr();
199 
200 //--- Command main program-----------------------------------------------------
201 int main ( int argc, char** argv )
202 //-----------------------------------------------------------------------------
203 {
204  fs::path pwd = fs::initial_path();
205  fs::path out;
206  Strings_t libs;
207  std::string pkgName;
208 
209  // declare a group of options that will be allowed only on command line
210  po::options_description generic("Generic options");
211  generic.add_options()
212  ("help,h",
213  "produce this help message")
214  ("package-name,p",
215  po::value<string>(),
216  "name of the package for which we create the configurables file")
217  ("input-libraries,i",
218  po::value<string>(),
219  "libraries to extract the component configurables from")
220  ("input-cfg,c",
221  po::value<string>(),
222  "path to the cfg file holding the description of the Configurable base "
223  "classes, the python module holding the Configurable definitions, etc...")
224  ("output-dir,o",
225  po::value<string>()->default_value("../genConf"),
226  "output directory for genconf files.")
227  ("debug-level,d",
228  po::value<int>()->default_value(0),
229  "debug level")
230  ("load-library,l",
231  po::value< Strings_t >()->composing(),
232  "preloading library")
233  ;
234 
235  // declare a group of options that will be allowed both on command line
236  // _and_ in configuration file
237  po::options_description config("Configuration");
238  config.add_options()
239  ("configurable-module",
240  po::value<string>()->default_value("AthenaCommon"),
241  "Name of the module holding the configurable classes")
242  ("configurable-default-name",
243  po::value<string>()->default_value("Configurable.DefaultName"),
244  "Default name for the configurable instance")
245  ("configurable-algorithm",
246  po::value<string>()->default_value("ConfigurableAlgorithm"),
247  "Name of the configurable base class for Algorithm components")
248  ("configurable-algtool",
249  po::value<string>()->default_value("ConfigurableAlgTool"),
250  "Name of the configurable base class for AlgTool components")
251  ("configurable-auditor",
252  po::value<string>()->default_value("ConfigurableAuditor"),
253  "Name of the configurable base class for Auditor components")
254  ("configurable-service",
255  po::value<string>()->default_value("ConfigurableService"),
256  "Name of the configurable base class for Service components")
257  ;
258 
259  po::options_description cmdline_options;
260  cmdline_options.add(generic).add(config);
261 
262  po::options_description config_file_options;
263  config_file_options.add(config);
264 
265  po::options_description visible("Allowed options");
266  visible.add(generic).add(config);
267 
268  po::variables_map vm;
269 
270  try {
271  po::store( po::command_line_parser(argc, argv).
272  options(cmdline_options).run(),
273  vm );
274 
275  po::notify(vm);
276 
277  // try to read configuration from the optionally given configuration file
278  if( vm.count("input-cfg") ) {
279  string cfgFileName = vm["input-cfg"].as<string>();
280  cfgFileName = fs::system_complete( fs::path( cfgFileName ) ).string();
281  std::ifstream ifs( cfgFileName.c_str() );
282  po::store( parse_config_file( ifs, config_file_options ), vm );
283  }
284 
285  po::notify(vm);
286  }
287  catch ( po::error& err ) {
288  cout << "ERR0R: error detected while parsing command options: "<< err.what() << endl;
289  return EXIT_FAILURE;
290  }
291 
292  //--- Process command options -----------------------------------------------
293  if( vm.count("help")) {
294  cout << visible << endl;
295  return EXIT_FAILURE;
296  }
297 
298  if( vm.count("package-name") ) {
299  pkgName = vm["package-name"].as<string>();
300  }
301  else {
302  cout << "ERROR: 'package-name' required" << endl;
303  cout << visible << endl;
304  return EXIT_FAILURE;
305  }
306 
307  if( vm.count("input-libraries") ) {
308  // re-shape the input arguments:
309  // - removes spurious spaces,
310  // - split into tokens.
311  Strings_t inputLibs;
312  {
313  string tmp = vm["input-libraries"].as<string>();
314  boost::trim(tmp);
315  boost::split( inputLibs, tmp,
316  boost::is_any_of(" "),
317  boost::token_compress_on );
318  }
319 
320  //
321  libs.reserve( inputLibs.size() );
322  for ( Strings_t::const_iterator iLib = inputLibs.begin();
323  iLib != inputLibs.end();
324  ++iLib ) {
325  std::string lib = fs::path(*iLib).stem().string();
326  if ( 0 == lib.find("lib") ) {
327  lib = lib.substr(3); // For *NIX remove "lib"
328  }
329  // remove duplicates
330  if ( !lib.empty() &&
331  std::find( libs.begin(), libs.end(), lib ) == libs.end() ) {
332  libs.push_back( lib );
333  }
334  } //> end loop over input-libraries
335  if ( libs.empty() ) {
336  cout << "ERROR: input component library(ies) required !\n"
337  << "ERROR: 'input-libraries' argument was ["
338  << vm["input-libraries"].as<string>()
339  << "]"
340  << endl;
341  return EXIT_FAILURE;
342  }
343  }
344  else {
345  cout << "ERROR: input component library(ies) required" << endl;
346  cout << visible << endl;
347  return EXIT_FAILURE;
348  }
349 
350  if( vm.count("output-dir") ) {
351  out = fs::system_complete( fs::path( vm["output-dir"].as<string>() ) );
352  }
353 
354  if ( vm.count("debug-level") ) {
355  PluginService::SetDebug( vm["debug-level"].as<int>() );
356  }
357 
358  if ( vm.count("load-library") ) {
359  Strings_t lLib_list = vm["load-library"].as< Strings_t >();
360  for (Strings_t::const_iterator lLib=lLib_list.begin();
361  lLib != lLib_list.end();
362  ++lLib) {
363  // load done through ROOT::Reflex helper class
364  SharedLibrary tmplib(*lLib) ;
365  tmplib.Load() ;
366  }
367  }
368 
369 
370  if ( !fs::exists( out ) ) {
371  try {
372  fs::create_directory(out);
373  }
374  catch ( fs::filesystem_error &err ) {
375  cout << "ERR0R: error creating directory: "<< err.what() << endl;
376  return EXIT_FAILURE;
377  }
378  }
379 
380  cout << ":::::: libraries : [ ";
381  copy( libs.begin(), libs.end(), ostream_iterator<string>(cout, " ") );
382  cout << "] ::::::" << endl;
383 
384  configGenerator py( pkgName, out.string() );
385  py.setConfigurableModule (vm["configurable-module"].as<string>());
386  py.setConfigurableDefaultName(vm["configurable-default-name"].as<string>());
387  py.setConfigurableAlgorithm (vm["configurable-algorithm"].as<string>());
388  py.setConfigurableAlgTool (vm["configurable-algtool"].as<string>());
389  py.setConfigurableAuditor (vm["configurable-auditor"].as<string>());
390  py.setConfigurableService (vm["configurable-service"].as<string>());
391 
392  int sc = EXIT_FAILURE;
393  try {
394  sc = py.genConfig( libs );
395  }
396  catch ( exception& e ) {
397  cout << "ERROR: Could not generate Configurable(s) !\n"
398  << "ERROR: Got exception: " << e.what() << endl;
399  return EXIT_FAILURE;
400  }
401 
402  if ( EXIT_SUCCESS == sc ) {
403  // create an empty __init__.py file in the output dir
404  fstream initPy( ( out / fs::path( "__init__.py" ) ).string().c_str(),
406  initPy << "## Hook for " << pkgName << " genConf module\n" << flush;
407  }
408 
409  cout << ":::::: libraries : [ ";
410  copy( libs.begin(), libs.end(), ostream_iterator<string>(cout, " ") );
411  cout << "] :::::: [DONE]" << endl;
412 
413  return sc;
414 }
415 
418 inline std::string getId(const Member & m) {
419  return (m.Properties().HasProperty("id") && (m.Properties().PropertyValue("id").TypeInfo() == typeid(std::string))) ?
420  m.Properties().PropertyAsString("id") :
421  m.Properties().PropertyAsString("name") ;
422 }
423 
424 template <class T>
425 IProperty *makeInstance(const Member &member, const vector<void*> &args)
426 {
427  Object dummy;
428  T* obj;
429 #if ROOT_VERSION_CODE < ROOT_VERSION(5,21,6)
430  obj = static_cast<T*>(member.Invoke(dummy,args).Address());
431 #else
432  member.Invoke(dummy,obj,args);
433 #endif
434  return dynamic_cast<IProperty*>(obj);
435 }
436 
437 
438 //-----------------------------------------------------------------------------
440 //-----------------------------------------------------------------------------
441 {
442  //--- Disable checking StatusCode -------------------------------------------
444 
445  const Strings_t::const_iterator endLib = libs.end();
446 
447  const std::string gaudiSvc = "GaudiCoreSvc";
448  const bool isGaudiSvc = ( std::find( libs.begin(), endLib, gaudiSvc ) != endLib );
449 
450  //--- Instantiate ApplicationMgr --------------------------------------------
451  if ( !isGaudiSvc && createAppMgr() ) {
452  cout << "ERROR: ApplicationMgr can not be created. Check environment" << endl;
453  return EXIT_FAILURE;
454  }
455 
456  //--- Iterate over component factories --------------------------------------
457  Scope factories = Scope::ByName(PLUGINSVC_FACTORY_NS);
458  if ( !factories ) {
459  cout << "ERROR: No PluginSvc factory namespace could be found" << endl;
460  return EXIT_FAILURE;
461  }
462 
463  ISvcLocator* svcLoc = Gaudi::svcLocator();
464  IInterface* dummySvc = new Service( "DummySvc", svcLoc );
465  dummySvc->addRef();
466 
467  bool allGood = true;
468 
469  // iterate over all the requested libraries
470  for ( Strings_t::const_iterator iLib=libs.begin(); iLib != endLib; ++iLib ) {
471 
472  std::cout << ":::: processing library: " << *iLib << "..." << std::endl;
473 
474  // reset state
475  m_importGaudiHandles = false;
476  m_pyBuf.str("");
477  m_dbBuf.str("");
478 
479  // Scan the pluginSvc namespace and store the "background" of already
480  // alive components, so we can extract our signal later on
481  set<string> bkgNames;
482  if ( !isGaudiSvc ) {
483  for ( Member_Iterator it = factories.FunctionMember_Begin();
484  it != factories.FunctionMember_End(); ++it ) {
485  string ident = getId(*it);
486  if ( PluginService::Debug() > 0 ) {
487  cout << "::: " << ident << endl;
488  }
489  bkgNames.insert( ident );
490  }
491  }
492  const set<string>::const_iterator bkgNamesEnd = bkgNames.end();
493 
494  //--- Load component library ----------------------------------------------
495  System::ImageHandle handle;
496  unsigned long err = System::loadDynamicLib( *iLib, &handle );
497  if ( err != 1 ) {
498  cout << "ERROR: " << System::getLastErrorString() << endl;
499  allGood = false;
500  continue;
501  }
502 
503  for ( Member_Iterator it = factories.FunctionMember_Begin();
504  it != factories.FunctionMember_End();
505  ++it ) {
506  const string ident = getId(*it);
507  if ( bkgNames.find(ident) != bkgNamesEnd ) {
508  if ( PluginService::Debug() > 0 ) {
509  cout << "\t==> skipping [" << ident << "]..." << endl;
510  }
511  continue;
512  }
513 
514  // Atlas contributed code (patch #1247)
515  // Skip the generation of configurables if the component does not come
516  // from the same library we are processing (i.e. we found a symbol that
517  // is coming from a library loaded by the linker).
518  // Windows implementation is empty.
519  if ( !DsoUtils::inDso( *it, DsoUtils::libNativeName(*iLib) ) ) {
520  cout << "WARNING: library [" << *iLib << "] requested factory "
521  << "from another library ["
522  << DsoUtils::dsoName(*it) << "]"
523  << " ==> [" << ident << "] !!"
524  << endl;
525  continue;
526  }
527 
528  const string rtype = it->TypeOf().ReturnType().Name();
529  string type;
530  bool known = true;
531  if ( ident == "ApplicationMgr" ) type = "ApplicationMgr";
532  else if ( rtype == "IInterface*" ) type = "IInterface";
533  else if ( rtype == "IAlgorithm*" ) type = "Algorithm";
534  else if ( rtype == "IService*" ) type = "Service";
535  else if ( rtype == "IAlgTool*" ) type = "AlgTool";
536  else if ( rtype == "IAuditor*" ) type = "Auditor";
537  else if ( rtype == "IConverter*" ) type = "Converter";
538  else if ( rtype == "DataObject*" ) type = "DataObject";
539  else type = "Unknown", known = false;
540  string name = ident;
541  // handle possible problems with templated components
542  boost::trim(name);
543 
544  cout << " - component: " << name << endl;
545 
546  if ( type == "IInterface" ) {
549  continue;
550  }
551 
552  if ( type == "Converter" || type == "DataObject" ) {
554  continue;
555  }
556 
557  //if ( type == "ApplicationMgr" ) {
560  //}
561 
562  if ( !known ) {
563  cout << "WARNING: Unknown (return) type [" << rtype << "] !!\n"
564  << "WARNING: component [" << ident << "] is skipped !"
565  << endl;
566  allGood = false;
567  continue;
568  }
569 
570  string cname = "DefaultName";
572  args.reserve( 3 );
573  if ( type == "AlgTool" ) {
574  args.resize( 3 );
575  args[0] = &cname;
576  args[1] = &type;
577  args[2] = dummySvc;
578  }
579  else {
580  args.resize( 2 );
581  args[0] = &cname;
582  args[1] = svcLoc;
583  }
584  IProperty* prop = 0;
585  try {
586  if ( type == "Algorithm" ) {
587  prop = makeInstance<IAlgorithm>(*it,args);
588  }
589  else if ( type == "Service") {
590  prop = makeInstance<IService>(*it,args);
591  }
592  else if ( type == "AlgTool") {
593  prop = makeInstance<IAlgTool>(*it,args);
594  }
595  else if ( type == "Auditor") {
596  prop = makeInstance<IAuditor>(*it,args);
597  }
598  else if ( type == "ApplicationMgr") {
599  //svcLoc->queryInterface(IProperty::interfaceID(), pp_cast<void>(&prop));
600  svcLoc->queryInterface(IProperty::interfaceID(), (void**)(&prop));
601  }
602  else {
603  prop = makeInstance<IInterface>(*it,args);
604  }
605  }
606  catch ( exception& e ) {
607  cout << "ERROR: Error instantiating " << name
608  << " from " << *iLib << endl;
609  cout << "ERROR: Got exception: " << e.what() << endl;
610  allGood = false;
611  continue;
612  }
613  catch ( ... ) {
614  cout << "ERROR: Error instantiating " << name
615  << " from " << *iLib << endl;
616  allGood = false;
617  continue;
618  }
619  if( prop ) {
620  if (genComponent( *iLib, name, type, prop->getProperties() )) {
621  allGood = false;
622  }
623  prop->release();
624  } else {
625  cout << "ERROR: could not cast IInterface* object to an IProperty* !\n"
626  << "ERROR: return type from PluginSvc is [" << rtype << "]...\n"
627  << "ERROR: NO Configurable will be generated for ["
628  << name << "] !"
629  << endl;
630  allGood = false;
631  }
632  } //> end loop over factories
633 
637  const std::string pyName = ( fs::path(m_outputDirName) /
638  fs::path(*iLib+"Conf.py") ).string();
639  const std::string dbName = ( fs::path(m_outputDirName) /
640  fs::path(*iLib+"_confDb.py") ).string();
641 
642  std::fstream py( pyName.c_str(),
644  std::fstream db( dbName.c_str(),
646 
647  genHeader ( py, db );
648  genBody ( py, db );
649  genTrailer( py, db );
650 
651  } //> end loop over libraries
652 
653  dummySvc->release();
654  dummySvc = 0;
655 
656  return allGood ? EXIT_SUCCESS : EXIT_FAILURE;
657 }
658 
660  const boost::format& frmt,
661  std::string indent = ""){
662 
663  std::string::size_type pos = 0, nxtpos = 0;
665 
666  while ( std::string::npos != pos ){
667  // find end of module name
668  nxtpos = m_configurable["Module"].find_first_of(',',pos);
669 
670  // Prepare import string
671  mod = m_configurable["Module"].substr(pos,nxtpos-pos);
672  std::ostringstream import;
673  import << boost::format(frmt) % mod;
674 
675  // append a normal import or a try/except enclosed one depending
676  // on availability of a fall-back module (next in the list)
677  if ( std::string::npos == nxtpos ) {
678  // last possible module
679  s << indent << import.str() << "\n" << flush;
680  pos = std::string::npos;
681  } else {
682  // we have a fallback for this
683  s << indent << "try:\n"
684  << indent << py_tab << import.str() << "\n"
685  << indent << "except ImportError:\n"
686  << flush;
687  pos = nxtpos+1;
688  }
689  // increase indentation level for next iteration
690  indent += py_tab;
691  }
692 }
693 
694 //-----------------------------------------------------------------------------
696  std::ostream& db )
697 //-----------------------------------------------------------------------------
698 {
699  // python file part
700  std::string now = Gaudi::Time::current().format(true);
701  py << "#" << now //<< "\n"
702  << "\"\"\"Automatically generated. DO NOT EDIT please\"\"\"\n";
703  if ( m_importGaudiHandles ) {
704  py << "from GaudiKernel.GaudiHandles import *\n";
705  }
706 
707  genImport(py,boost::format("from %1%.Configurable import *"));
708 
709  // db file part
710  db << "## -*- python -*- \n"
711  << "# db file automatically generated by genconf on: "
712  << now; // << "\n";
713  db << "## insulates outside world against anything bad that could happen\n"
714  << "## also prevents global scope pollution\n"
715  << "def _fillCfgDb():\n";
716  genImport(db,boost::format("from %1%.ConfigurableDb import CfgDb"),py_tab);
717 
718  db << "\n"
719  << py_tab << "# get a handle on the repository of Configurables\n"
720  << py_tab << "cfgDb = CfgDb()\n"
721  << "\n"
722  << py_tab << "# populate the repository with informations on Configurables \n"
723  << "\n"
724  << flush;
725 }
726 //-----------------------------------------------------------------------------
728  std::ostream& db )
729 //-----------------------------------------------------------------------------
730 {
731  // db file part
732  db << py_tab << "return #_fillCfgDb\n"
733  << "# fill cfgDb at module import...\n"
734  << "try:\n"
735  << py_tab << "_fillCfgDb()\n"
736  << py_tab << "#house cleaning...\n"
737  << py_tab << "del _fillCfgDb\n"
738  << "except Exception,err:\n"
739  << py_tab << "print \"Py:ConfigurableDb ERROR Problem with [%s] content!"
740  << "\" % __name__\n"
741  << py_tab << "print \"Py:ConfigurableDb ERROR\",err\n"
742  << py_tab << "print \"Py:ConfigurableDb ERROR ==> culprit is package ["
743  << m_pkgName << "] !\"\n"
744  << std::flush;
745 }
746 
747 //-----------------------------------------------------------------------------
748 int
750  const std::string& componentName,
751  const std::string& componentType,
752  const vector<Property*>& properties )
753 //-----------------------------------------------------------------------------
754 {
755  string cname = componentName;
756  pythonizeName(cname);
757 
758  typedef GaudiUtils::HashMap<std::string, std::string> PropertyDoc_t;
759  PropertyDoc_t propDoc;
760 
761  m_pyBuf << "\n";
762  m_pyBuf << "class " << cname
763  << "( " << m_configurable[componentType] << " ) :"
764  << "\n";
765  m_pyBuf << " __slots__ = { \n";
766  for ( vector<Property*>::const_iterator it = properties.begin() ;
767  it != properties.end(); ++it ) {
768 
769  const string pname = (*it)->name();
770  // Validate property name (it must be a valid Python identifier)
771  if (!boost::regex_match(pname, pythonIdentifier)) {
772  std::cout << "ERROR: invalid property name \"" << pname
773  << "\" in component " << cname
774  << " (invalid Python identifier)" << std::endl;
775  // try to make the buffer at least more or less valid python code.
776  m_pyBuf << " #ERROR-invalid identifier '" << pname << "'\n"
777  << " }\n";
778  return 1;
779  }
780 
781  string pvalue, ptype;
782  pythonizeValue( (*it), pvalue, ptype );
783  m_pyBuf << " '" << pname << "' : " << pvalue <<", # " << ptype << "\n";
784 
785  if ( (*it)->documentation() != "none" ) {
786  propDoc[pname] = (*it)->documentation();
787  }
788 
789  }
790  m_pyBuf << " }\n";
791  m_pyBuf << " _propertyDocDct = { \n";
792  for ( PropertyDoc_t::const_iterator iProp = propDoc.begin();
793  iProp != propDoc.end();
794  ++iProp ) {
795  m_pyBuf << std::setw(5)
796  << "'" << iProp->first << "' : "
797  << "\"\"\" " << iProp->second << " \"\"\",\n";
798  }
799  m_pyBuf << " }\n";
800 
801  m_pyBuf
802  << " def __init__(self, name = " << m_configurable["DefaultName"]
803  << ", **kwargs):\n"
804  << " super(" << cname << ", self).__init__(name)\n"
805  << " for n,v in kwargs.items():\n"
806  << " setattr(self, n, v)\n"
807  << " def getDlls( self ):\n"
808  << " return '" << libName << "'\n"
809  << " def getType( self ):\n"
810  << " return '" << componentName << "'\n"
811  << " pass # class " << cname << "\n"
812  << flush;
813 
814  // name of the auto-generated module
815  const string pyName = ( fs::path(m_outputDirName) /
816  fs::path(libName+"Conf.py") ).string();
817  const string modName = fs::basename( fs::path( pyName ).leaf() );
818 
819  // now the db part
820  m_dbBuf
821  << py_tab << "cfgDb.add( configurable = '" << cname << "',\n"
822  << py_tab << " package = '" << m_pkgName << "',\n"
823  << py_tab << " module = '" << m_pkgName << "." << modName << "',\n"
824  << py_tab << " lib = '" << libName << "' )\n"
825  << flush;
826 
827  return 0;
828 }
829 //-----------------------------------------------------------------------------
830 void configGenerator::pythonizeName( string& name )
831 //-----------------------------------------------------------------------------
832 {
833  static string in("<>&*,: ().");
834  static string out("__rp__s___");
835  for ( string::iterator i = name.begin(); i != name.end(); ++i ) {
836  if ( in.find(*i) != string::npos ) *i = out[in.find(*i)];
837  }
838 }
839 
840 //-----------------------------------------------------------------------------
842  string& pvalue, string& ptype )
843 //-----------------------------------------------------------------------------
844 {
845  const std::string cvalue = p->toString();
846  const type_info& ti = *p->type_info();
847  if ( ti == typeid(bool) ) {
848  pvalue = ( cvalue == "0" || cvalue == "False" || cvalue == "false" )
849  ? "False"
850  : "True";
851  ptype = "bool";
852  }
853  else if ( ti == typeid(char) || ti == typeid(signed char)
854  || ti == typeid(unsigned char) ||
855  ti == typeid(short) || ti == typeid(unsigned short) ||
856  ti == typeid(int) || ti == typeid(unsigned int) ||
857  ti == typeid(long) || ti == typeid(unsigned long) ) {
858  pvalue = cvalue;
859  ptype = "int";
860  }
861  else if ( ti == typeid(long long) || ti == typeid(unsigned long long) ) {
862  pvalue = cvalue + "L";
863  ptype = "long";
864  }
865  else if ( ti == typeid(float) || ti == typeid(double) ) {
866  // forces python to handle this as a float: put a dot in there...
867  pvalue = boost::to_lower_copy(cvalue);
868  if ( pvalue == "nan" ) {
869  pvalue = "float('nan')";
870  std::cout << "WARNING: default value for ["
871  << p->name() << "] is NaN !!"
872  << std::endl;
873  } else if ( std::string::npos == pvalue.find(".") &&
874  std::string::npos == pvalue.find("e") ) {
875  pvalue = cvalue + ".0";
876  }
877  ptype = "float";
878  }
879  else if ( ti == typeid(string) ) {
880 
881  pvalue = "'"+cvalue+"'";
882  ptype = "str";
883  }
884  else if ( ti == typeid(GaudiHandleBase) ) {
885  m_importGaudiHandles = true;
886  const GaudiHandleProperty& hdl
887  = dynamic_cast<const GaudiHandleProperty&>(*p);
888  const GaudiHandleBase& base = hdl.value();
889 
890  pvalue = base.pythonRepr();
891  ptype = "GaudiHandle";
892  }
893  else if ( ti == typeid(GaudiHandleArrayBase) ) {
894  m_importGaudiHandles = true;
895  const GaudiHandleArrayProperty& hdl
896  = dynamic_cast<const GaudiHandleArrayProperty&>(*p);
897  const GaudiHandleArrayBase& base = hdl.value();
898 
899  pvalue = base.pythonRepr();
900  ptype = "GaudiHandleArray";
901  }
902  else {
903  std::ostringstream v_str;
904  v_str.setf(std::ios::fixed); // to correctly display floats
905  p->toStream(v_str);
906  pvalue = v_str.str();
907  ptype = "list";
908  }
909 }
910 
911 //-----------------------------------------------------------------------------
913 //-----------------------------------------------------------------------------
914 {
916  SmartIF<IProperty> propMgr ( iface );
917  SmartIF<IAppMgrUI> appUI ( iface );
918 
919  if ( propMgr.isValid() && appUI.isValid() ) {
920  propMgr->setProperty( "JobOptionsType", "NONE" ); // No job options
921  propMgr->setProperty( "AppName", ""); // No initial printout message
922  propMgr->setProperty( "OutputLevel", "7"); // No other printout messages
923  appUI->configure();
924  return EXIT_SUCCESS;
925  }
926  else {
927  return EXIT_FAILURE;
928  }
929 }

Generated at Wed Nov 28 2012 12:17:16 for Gaudi Framework, version v23r5 by Doxygen version 1.8.2 written by Dimitri van Heesch, © 1997-2004