Gaudi Framework, version v25r0

Home   Generated: Mon Feb 17 2014
 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/algorithm/string/replace.hpp"
36 #include "boost/format.hpp"
37 #include "boost/regex.hpp"
38 
39 #include "GaudiKernel/System.h"
41 #include "GaudiKernel/IProperty.h"
42 #include "GaudiKernel/IAppMgrUI.h"
43 #include "GaudiKernel/IAlgorithm.h"
44 #include "GaudiKernel/IAlgTool.h"
45 #include "GaudiKernel/IAuditor.h"
46 #include "GaudiKernel/IAppMgrUI.h"
47 #include "GaudiKernel/Service.h"
48 #include "GaudiKernel/Bootstrap.h"
49 #include "GaudiKernel/SmartIF.h"
50 #include "GaudiKernel/HashMap.h"
52 
53 #include "GaudiKernel/Auditor.h"
54 #include "GaudiKernel/Service.h"
55 #include "GaudiKernel/AlgTool.h"
56 #include "GaudiKernel/Algorithm.h"
57 
58 #include "GaudiKernel/Time.h"
59 
60 #include <Gaudi/PluginService.h>
61 
62 #include <algorithm>
63 #include <iostream>
64 #include <fstream>
65 #include <sstream>
66 #include <exception>
67 #include <set>
68 #include <vector>
69 
70 #include "DsoUtils.h"
71 
72 namespace po = boost::program_options;
73 namespace fs = boost::filesystem;
74 
75 using namespace std;
76 
77 class IConverter;
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, const string& userModule );
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  std::string userModule;
209 
210  // declare a group of options that will be allowed only on command line
211  po::options_description generic("Generic options");
212  generic.add_options()
213  ("help,h",
214  "produce this help message")
215  ("package-name,p",
216  po::value<string>(),
217  "name of the package for which we create the configurables file")
218  ("input-libraries,i",
219  po::value<string>(),
220  "libraries to extract the component configurables from")
221  ("input-cfg,c",
222  po::value<string>(),
223  "path to the cfg file holding the description of the Configurable base "
224  "classes, the python module holding the Configurable definitions, etc...")
225  ("output-dir,o",
226  po::value<string>()->default_value("../genConf"),
227  "output directory for genconf files.")
228  ("debug-level,d",
229  po::value<int>()->default_value(0),
230  "debug level")
231  ("load-library,l",
232  po::value< Strings_t >()->composing(),
233  "preloading library")
234  ("user-module,m",
235  po::value<string>(),
236  "user-defined module to be imported by the genConf-generated one")
237  ;
238 
239  // declare a group of options that will be allowed both on command line
240  // _and_ in configuration file
241  po::options_description config("Configuration");
242  config.add_options()
243  ("configurable-module",
244  po::value<string>()->default_value("AthenaCommon"),
245  "Name of the module holding the configurable classes")
246  ("configurable-default-name",
247  po::value<string>()->default_value("Configurable.DefaultName"),
248  "Default name for the configurable instance")
249  ("configurable-algorithm",
250  po::value<string>()->default_value("ConfigurableAlgorithm"),
251  "Name of the configurable base class for Algorithm components")
252  ("configurable-algtool",
253  po::value<string>()->default_value("ConfigurableAlgTool"),
254  "Name of the configurable base class for AlgTool components")
255  ("configurable-auditor",
256  po::value<string>()->default_value("ConfigurableAuditor"),
257  "Name of the configurable base class for Auditor components")
258  ("configurable-service",
259  po::value<string>()->default_value("ConfigurableService"),
260  "Name of the configurable base class for Service components")
261  ;
262 
263  po::options_description cmdline_options;
264  cmdline_options.add(generic).add(config);
265 
266  po::options_description config_file_options;
267  config_file_options.add(config);
268 
269  po::options_description visible("Allowed options");
270  visible.add(generic).add(config);
271 
272  po::variables_map vm;
273 
274  try {
275  po::store( po::command_line_parser(argc, argv).
276  options(cmdline_options).run(),
277  vm );
278 
279  po::notify(vm);
280 
281  // try to read configuration from the optionally given configuration file
282  if( vm.count("input-cfg") ) {
283  string cfgFileName = vm["input-cfg"].as<string>();
284  cfgFileName = fs::system_complete( fs::path( cfgFileName ) ).string();
285  std::ifstream ifs( cfgFileName.c_str() );
286  po::store( parse_config_file( ifs, config_file_options ), vm );
287  }
288 
289  po::notify(vm);
290  }
291  catch ( po::error& err ) {
292  cout << "ERR0R: error detected while parsing command options: "<< err.what() << endl;
293  return EXIT_FAILURE;
294  }
295 
296  //--- Process command options -----------------------------------------------
297  if( vm.count("help")) {
298  cout << visible << endl;
299  return EXIT_FAILURE;
300  }
301 
302  if( vm.count("package-name") ) {
303  pkgName = vm["package-name"].as<string>();
304  }
305  else {
306  cout << "ERROR: 'package-name' required" << endl;
307  cout << visible << endl;
308  return EXIT_FAILURE;
309  }
310 
311  if( vm.count("user-module") ) {
312  userModule = vm["user-module"].as<string>();
313  cout << "INFO: will import user module " << userModule << endl;
314  }
315 
316  if( vm.count("input-libraries") ) {
317  // re-shape the input arguments:
318  // - removes spurious spaces,
319  // - split into tokens.
320  Strings_t inputLibs;
321  {
322  string tmp = vm["input-libraries"].as<string>();
323  boost::trim(tmp);
324  boost::split( inputLibs, tmp,
325  boost::is_any_of(" "),
326  boost::token_compress_on );
327  }
328 
329  //
330  libs.reserve( inputLibs.size() );
331  for ( Strings_t::const_iterator iLib = inputLibs.begin();
332  iLib != inputLibs.end();
333  ++iLib ) {
334  std::string lib = fs::path(*iLib).stem().string();
335  if ( 0 == lib.find("lib") ) {
336  lib = lib.substr(3); // For *NIX remove "lib"
337  }
338  // remove duplicates
339  if ( !lib.empty() &&
340  std::find( libs.begin(), libs.end(), lib ) == libs.end() ) {
341  libs.push_back( lib );
342  }
343  } //> end loop over input-libraries
344  if ( libs.empty() ) {
345  cout << "ERROR: input component library(ies) required !\n"
346  << "ERROR: 'input-libraries' argument was ["
347  << vm["input-libraries"].as<string>()
348  << "]"
349  << endl;
350  return EXIT_FAILURE;
351  }
352  }
353  else {
354  cout << "ERROR: input component library(ies) required" << endl;
355  cout << visible << endl;
356  return EXIT_FAILURE;
357  }
358 
359  if( vm.count("output-dir") ) {
360  out = fs::system_complete( fs::path( vm["output-dir"].as<string>() ) );
361  }
362 
363  if ( vm.count("debug-level") ) {
364  Gaudi::PluginService::SetDebug( vm["debug-level"].as<int>() );
365  }
366 
367  if ( vm.count("load-library") ) {
368  Strings_t lLib_list = vm["load-library"].as< Strings_t >();
369  for (Strings_t::const_iterator lLib=lLib_list.begin();
370  lLib != lLib_list.end();
371  ++lLib) {
372  // load done through Gaudi helper class
373  System::ImageHandle tmp; // we ignore the library handle
374  unsigned long err = System::loadDynamicLib(*lLib, &tmp);
375  if (err != 1) {
376  cout << "WARNING: failed to load: "<< *lLib << endl;
377  }
378  }
379  }
380 
381 
382  if ( !fs::exists( out ) ) {
383  try {
384  fs::create_directory(out);
385  }
386  catch ( fs::filesystem_error &err ) {
387  cout << "ERROR: error creating directory: "<< err.what() << endl;
388  return EXIT_FAILURE;
389  }
390  }
391 
392  cout << ":::::: libraries : [ ";
393  copy( libs.begin(), libs.end(), ostream_iterator<string>(cout, " ") );
394  cout << "] ::::::" << endl;
395 
396  configGenerator py( pkgName, out.string() );
397  py.setConfigurableModule (vm["configurable-module"].as<string>());
398  py.setConfigurableDefaultName(vm["configurable-default-name"].as<string>());
399  py.setConfigurableAlgorithm (vm["configurable-algorithm"].as<string>());
400  py.setConfigurableAlgTool (vm["configurable-algtool"].as<string>());
401  py.setConfigurableAuditor (vm["configurable-auditor"].as<string>());
402  py.setConfigurableService (vm["configurable-service"].as<string>());
403 
404  int sc = EXIT_FAILURE;
405  try {
406  sc = py.genConfig( libs, userModule );
407  }
408  catch ( exception& e ) {
409  cout << "ERROR: Could not generate Configurable(s) !\n"
410  << "ERROR: Got exception: " << e.what() << endl;
411  return EXIT_FAILURE;
412  }
413 
414  if ( EXIT_SUCCESS == sc ) {
415  // create an empty __init__.py file in the output dir
416  fstream initPy( ( out / fs::path( "__init__.py" ) ).string().c_str(),
418  initPy << "## Hook for " << pkgName << " genConf module\n" << flush;
419  }
420 
421  cout << ":::::: libraries : [ ";
422  copy( libs.begin(), libs.end(), ostream_iterator<string>(cout, " ") );
423  cout << "] :::::: [DONE]" << endl;
424 
425  return sc;
426 }
427 
428 //-----------------------------------------------------------------------------
429 int configGenerator::genConfig( const Strings_t& libs, const string& userModule )
430 //-----------------------------------------------------------------------------
431 {
432  //--- Disable checking StatusCode -------------------------------------------
434 
435  const Strings_t::const_iterator endLib = libs.end();
436 
437  const std::string gaudiSvc = "GaudiCoreSvc";
438  const bool isGaudiSvc = ( std::find( libs.begin(), endLib, gaudiSvc ) != endLib );
439 
440  //--- Instantiate ApplicationMgr --------------------------------------------
441  if ( !isGaudiSvc && createAppMgr() ) {
442  cout << "ERROR: ApplicationMgr can not be created. Check environment" << endl;
443  return EXIT_FAILURE;
444  }
445 
446  //--- Iterate over component factories --------------------------------------
447  using Gaudi::PluginService::Details::Registry;
448  Registry& registry = Registry::instance();
449 
450  std::set<std::string> bkgNames = registry.loadedFactories();
451 
452  ISvcLocator* svcLoc = Gaudi::svcLocator();
453  IInterface* dummySvc = new Service( "DummySvc", svcLoc );
454  dummySvc->addRef();
455 
456  bool allGood = true;
457 
458  // iterate over all the requested libraries
459  for ( Strings_t::const_iterator iLib=libs.begin(); iLib != endLib; ++iLib ) {
460 
461  std::cout << ":::: processing library: " << *iLib << "..." << std::endl;
462 
463  // reset state
464  m_importGaudiHandles = false;
465  m_pyBuf.str("");
466  m_dbBuf.str("");
467 
468  //--- Load component library ----------------------------------------------
469  System::ImageHandle handle;
470  unsigned long err = System::loadDynamicLib( *iLib, &handle );
471  if ( err != 1 ) {
472  cout << "ERROR: " << System::getLastErrorString() << endl;
473  allGood = false;
474  continue;
475  }
476 
477  std::set<std::string> factories = registry.loadedFactories();
478 
479  for ( std::set<std::string>::iterator it = factories.begin();
480  it != factories.end(); ++it ) {
481  const string ident = *it;
482  if ( bkgNames.find(ident) != bkgNames.end() ) {
484  cout << "\t==> skipping [" << ident << "]..." << endl;
485  }
486  continue;
487  }
488 
489  const Registry::FactoryInfo info = registry.getInfo(*it);
490  const string rtype = info.rtype;
491 
492  // do not generate configurables for the Reflex-compatible aliases
493  if (info.properties.find("ReflexName") != info.properties.end())
494  continue;
495 
496  // Atlas contributed code (patch #1247)
497  // Skip the generation of configurables if the component does not come
498  // from the same library we are processing (i.e. we found a symbol that
499  // is coming from a library loaded by the linker).
500  if ( !DsoUtils::inDso( info.ptr, DsoUtils::libNativeName(*iLib) ) ) {
501  cout << "WARNING: library [" << *iLib << "] exposes factory ["
502  << ident << "] which is declared in ["
503  << DsoUtils::dsoName(info.ptr) << "] !!" << endl;
504  continue;
505  }
506 
507  string type;
508  bool known = true;
509  if ( ident == "ApplicationMgr" ) type = "ApplicationMgr";
510  else if ( rtype == typeid(IInterface*).name() ) type = "IInterface";
511  else if ( rtype == typeid(IAlgorithm*).name() ) type = "Algorithm";
512  else if ( rtype == typeid(IService* ).name() ) type = "Service";
513  else if ( rtype == typeid(IAlgTool* ).name() ) type = "AlgTool";
514  else if ( rtype == typeid(IAuditor* ).name() ) type = "Auditor";
515  else if ( rtype == typeid(IConverter*).name() ) type = "Converter";
516  else if ( rtype == typeid(DataObject*).name() ) type = "DataObject";
517  else type = "Unknown", known = false;
518  string name = ident;
519  // handle possible problems with templated components
520  boost::trim(name);
521 
522  if ( type == "IInterface" ) {
525  continue;
526  }
527 
528  if ( type == "Converter" || type == "DataObject" ) {
530  continue;
531  }
532 
533  if ( !known ) {
534  cout << "WARNING: Unknown (return) type [" << rtype << "] !!\n"
535  << "WARNING: component [" << ident << "] is skipped !"
536  << endl;
537  allGood = false;
538  continue;
539  }
540 
541  cout << " - component: " << info.className << " (";
542  if (info.className != name)
543  cout << name << ": ";
544  cout << type << ")" << endl;
545 
546  string cname = "DefaultName";
547  SmartIF<IProperty> prop;
548  try {
549  if ( type == "Algorithm" ) {
550  prop = SmartIF<IAlgorithm>(Algorithm::Factory::create(ident, cname, svcLoc));
551  }
552  else if ( type == "Service") {
553  prop = SmartIF<IService>(Service::Factory::create(ident, cname, svcLoc));
554  }
555  else if ( type == "AlgTool") {
556  prop = SmartIF<IAlgTool>(AlgTool::Factory::create(ident, cname, type, dummySvc));
557  // FIXME: AlgTool base class increase artificially by 1 the refcount.
558  prop->release();
559  }
560  else if ( type == "Auditor") {
561  prop = SmartIF<IAuditor>(Auditor::Factory::create(ident, cname, svcLoc));
562  }
563  else if ( type == "ApplicationMgr") {
564  prop = SmartIF<ISvcLocator>(svcLoc);
565  }
566  else {
567  continue; // unknown
568  }
569  }
570  catch ( exception& e ) {
571  cout << "ERROR: Error instantiating " << name
572  << " from " << *iLib << endl;
573  cout << "ERROR: Got exception: " << e.what() << endl;
574  allGood = false;
575  continue;
576  }
577  catch ( ... ) {
578  cout << "ERROR: Error instantiating " << name
579  << " from " << *iLib << endl;
580  allGood = false;
581  continue;
582  }
583  if( prop ) {
584  if (genComponent( *iLib, name, type, prop->getProperties() )) {
585  allGood = false;
586  }
587  prop.reset();
588  } else {
589  cout << "ERROR: could not cast IInterface* object to an IProperty* !\n"
590  << "ERROR: return type from PluginSvc is [" << rtype << "]...\n"
591  << "ERROR: NO Configurable will be generated for ["
592  << name << "] !"
593  << endl;
594  allGood = false;
595  }
596  } //> end loop over factories
597 
601  const std::string pyName = ( fs::path(m_outputDirName) /
602  fs::path(*iLib+"Conf.py") ).string();
603  const std::string dbName = ( fs::path(m_outputDirName) /
604  fs::path(*iLib+"_confDb.py") ).string();
605 
606  std::fstream py( pyName.c_str(),
608  std::fstream db( dbName.c_str(),
610 
611  genHeader ( py, db );
612  if (!userModule.empty())
613  py << "from " << userModule << " import *" <<endl;
614  genBody ( py, db );
615  genTrailer( py, db );
616 
617  } //> end loop over libraries
618 
619  dummySvc->release();
620  dummySvc = 0;
621 
622  return allGood ? EXIT_SUCCESS : EXIT_FAILURE;
623 }
624 
626  const boost::format& frmt,
627  std::string indent = ""){
628 
629  std::string::size_type pos = 0, nxtpos = 0;
631 
632  while ( std::string::npos != pos ){
633  // find end of module name
634  nxtpos = m_configurable["Module"].find_first_of(',',pos);
635 
636  // Prepare import string
637  mod = m_configurable["Module"].substr(pos,nxtpos-pos);
638  std::ostringstream import;
639  import << boost::format(frmt) % mod;
640 
641  // append a normal import or a try/except enclosed one depending
642  // on availability of a fall-back module (next in the list)
643  if ( std::string::npos == nxtpos ) {
644  // last possible module
645  s << indent << import.str() << "\n" << flush;
646  pos = std::string::npos;
647  } else {
648  // we have a fallback for this
649  s << indent << "try:\n"
650  << indent << py_tab << import.str() << "\n"
651  << indent << "except ImportError:\n"
652  << flush;
653  pos = nxtpos+1;
654  }
655  // increase indentation level for next iteration
656  indent += py_tab;
657  }
658 }
659 
660 //-----------------------------------------------------------------------------
662  std::ostream& db )
663 //-----------------------------------------------------------------------------
664 {
665  // python file part
666  std::string now = Gaudi::Time::current().format(true);
667  py << "#" << now //<< "\n"
668  << "\"\"\"Automatically generated. DO NOT EDIT please\"\"\"\n";
669  if ( m_importGaudiHandles ) {
670  py << "from GaudiKernel.GaudiHandles import *\n";
671  }
672 
673  genImport(py,boost::format("from %1%.Configurable import *"));
674 
675  // db file part
676  db << "## -*- python -*- \n"
677  << "# db file automatically generated by genconf on: "
678  << now; // << "\n";
679  db << "## insulates outside world against anything bad that could happen\n"
680  << "## also prevents global scope pollution\n"
681  << "def _fillCfgDb():\n";
682  genImport(db,boost::format("from %1%.ConfigurableDb import CfgDb"),py_tab);
683 
684  db << "\n"
685  << py_tab << "# get a handle on the repository of Configurables\n"
686  << py_tab << "cfgDb = CfgDb()\n"
687  << "\n"
688  << py_tab << "# populate the repository with informations on Configurables \n"
689  << "\n"
690  << flush;
691 }
692 //-----------------------------------------------------------------------------
694  std::ostream& db )
695 //-----------------------------------------------------------------------------
696 {
697  // db file part
698  db << py_tab << "return #_fillCfgDb\n"
699  << "# fill cfgDb at module import...\n"
700  << "try:\n"
701  << py_tab << "_fillCfgDb()\n"
702  << py_tab << "#house cleaning...\n"
703  << py_tab << "del _fillCfgDb\n"
704  << "except Exception,err:\n"
705  << py_tab << "print \"Py:ConfigurableDb ERROR Problem with [%s] content!"
706  << "\" % __name__\n"
707  << py_tab << "print \"Py:ConfigurableDb ERROR\",err\n"
708  << py_tab << "print \"Py:ConfigurableDb ERROR ==> culprit is package ["
709  << m_pkgName << "] !\"\n"
710  << std::flush;
711 }
712 
713 //-----------------------------------------------------------------------------
714 int
716  const std::string& componentName,
717  const std::string& componentType,
718  const vector<Property*>& properties )
719 //-----------------------------------------------------------------------------
720 {
721  string cname = componentName;
722  pythonizeName(cname);
723 
724  typedef GaudiUtils::HashMap<std::string, std::string> PropertyDoc_t;
725  PropertyDoc_t propDoc;
726 
727  m_pyBuf << "\n";
728  m_pyBuf << "class " << cname
729  << "( " << m_configurable[componentType] << " ) :"
730  << "\n";
731  m_pyBuf << " __slots__ = { \n";
732  for ( vector<Property*>::const_iterator it = properties.begin() ;
733  it != properties.end(); ++it ) {
734 
735  const string pname = (*it)->name();
736  // Validate property name (it must be a valid Python identifier)
737  if (!boost::regex_match(pname, pythonIdentifier)) {
738  std::cout << "ERROR: invalid property name \"" << pname
739  << "\" in component " << cname
740  << " (invalid Python identifier)" << std::endl;
741  // try to make the buffer at least more or less valid python code.
742  m_pyBuf << " #ERROR-invalid identifier '" << pname << "'\n"
743  << " }\n";
744  return 1;
745  }
746 
747  string pvalue, ptype;
748  pythonizeValue( (*it), pvalue, ptype );
749  m_pyBuf << " '" << pname << "' : " << pvalue <<", # " << ptype << "\n";
750 
751  if ( (*it)->documentation() != "none" ) {
752  propDoc[pname] = (*it)->documentation();
753  }
754 
755  }
756  m_pyBuf << " }\n";
757  m_pyBuf << " _propertyDocDct = { \n";
758  for ( PropertyDoc_t::const_iterator iProp = propDoc.begin();
759  iProp != propDoc.end();
760  ++iProp ) {
761  m_pyBuf << std::setw(5)
762  << "'" << iProp->first << "' : "
763  << "\"\"\" " << iProp->second << " \"\"\",\n";
764  }
765  m_pyBuf << " }\n";
766 
767  m_pyBuf
768  << " def __init__(self, name = " << m_configurable["DefaultName"]
769  << ", **kwargs):\n"
770  << " super(" << cname << ", self).__init__(name)\n"
771  << " for n,v in kwargs.items():\n"
772  << " setattr(self, n, v)\n"
773  << " def getDlls( self ):\n"
774  << " return '" << libName << "'\n"
775  << " def getType( self ):\n"
776  << " return '" << componentName << "'\n"
777  << " pass # class " << cname << "\n"
778  << flush;
779 
780  // name of the auto-generated module
781  const string pyName = ( fs::path(m_outputDirName) /
782  fs::path(libName+"Conf.py") ).string();
783  const string modName = fs::basename( fs::path( pyName ).leaf() );
784 
785  // now the db part
786  m_dbBuf
787  << py_tab << "cfgDb.add( configurable = '" << cname << "',\n"
788  << py_tab << " package = '" << m_pkgName << "',\n"
789  << py_tab << " module = '" << m_pkgName << "." << modName << "',\n"
790  << py_tab << " lib = '" << libName << "' )\n"
791  << flush;
792 
793  return 0;
794 }
795 //-----------------------------------------------------------------------------
796 void configGenerator::pythonizeName( string& name )
797 //-----------------------------------------------------------------------------
798 {
799  static string in("<>&*,: ().");
800  static string out("__rp__s___");
801  boost::algorithm::replace_all(name, ", ", ",");
802  for ( string::iterator i = name.begin(); i != name.end(); ++i ) {
803  if ( in.find(*i) != string::npos ) *i = out[in.find(*i)];
804  }
805 }
806 
807 //-----------------------------------------------------------------------------
809  string& pvalue, string& ptype )
810 //-----------------------------------------------------------------------------
811 {
812  const std::string cvalue = p->toString();
813  const type_info& ti = *p->type_info();
814  if ( ti == typeid(bool) ) {
815  pvalue = ( cvalue == "0" || cvalue == "False" || cvalue == "false" )
816  ? "False"
817  : "True";
818  ptype = "bool";
819  }
820  else if ( ti == typeid(char) || ti == typeid(signed char)
821  || ti == typeid(unsigned char) ||
822  ti == typeid(short) || ti == typeid(unsigned short) ||
823  ti == typeid(int) || ti == typeid(unsigned int) ||
824  ti == typeid(long) || ti == typeid(unsigned long) ) {
825  pvalue = cvalue;
826  ptype = "int";
827  }
828  else if ( ti == typeid(long long) || ti == typeid(unsigned long long) ) {
829  pvalue = cvalue + "L";
830  ptype = "long";
831  }
832  else if ( ti == typeid(float) || ti == typeid(double) ) {
833  // forces python to handle this as a float: put a dot in there...
834  pvalue = boost::to_lower_copy(cvalue);
835  if ( pvalue == "nan" ) {
836  pvalue = "float('nan')";
837  std::cout << "WARNING: default value for ["
838  << p->name() << "] is NaN !!"
839  << std::endl;
840  } else if ( std::string::npos == pvalue.find(".") &&
841  std::string::npos == pvalue.find("e") ) {
842  pvalue = cvalue + ".0";
843  }
844  ptype = "float";
845  }
846  else if ( ti == typeid(string) ) {
847 
848  pvalue = "'"+cvalue+"'";
849  ptype = "str";
850  }
851  else if ( ti == typeid(GaudiHandleBase) ) {
852  m_importGaudiHandles = true;
853  const GaudiHandleProperty& hdl
854  = dynamic_cast<const GaudiHandleProperty&>(*p);
855  const GaudiHandleBase& base = hdl.value();
856 
857  pvalue = base.pythonRepr();
858  ptype = "GaudiHandle";
859  }
860  else if ( ti == typeid(GaudiHandleArrayBase) ) {
861  m_importGaudiHandles = true;
862  const GaudiHandleArrayProperty& hdl
863  = dynamic_cast<const GaudiHandleArrayProperty&>(*p);
864  const GaudiHandleArrayBase& base = hdl.value();
865 
866  pvalue = base.pythonRepr();
867  ptype = "GaudiHandleArray";
868  }
869  else {
870  std::ostringstream v_str;
871  v_str.setf(std::ios::fixed); // to correctly display floats
872  p->toStream(v_str);
873  pvalue = v_str.str();
874  ptype = "list";
875  }
876 }
877 
878 //-----------------------------------------------------------------------------
880 //-----------------------------------------------------------------------------
881 {
883  SmartIF<IProperty> propMgr ( iface );
884  SmartIF<IAppMgrUI> appUI ( iface );
885 
886  if ( propMgr.isValid() && appUI.isValid() ) {
887  propMgr->setProperty( "JobOptionsType", "NONE" ); // No job options
888  propMgr->setProperty( "AppName", ""); // No initial printout message
889  propMgr->setProperty( "OutputLevel", "7"); // No other printout messages
890  appUI->configure();
891  return EXIT_SUCCESS;
892  }
893  else {
894  return EXIT_FAILURE;
895  }
896 }

Generated at Mon Feb 17 2014 14:37:46 for Gaudi Framework, version v25r0 by Doxygen version 1.8.2 written by Dimitri van Heesch, © 1997-2004