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
80 typedef std::vector<std::string> Strings_t;
81 typedef std::vector<fs::path> LibPathNames_t;
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 
101  stringstream m_pyBuf;
102 
106 
111  stringstream m_dbBuf;
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  ("no-init",
238  "do not generate the (empty) __init__.py")
239  ;
240 
241  // declare a group of options that will be allowed both on command line
242  // _and_ in configuration file
243  po::options_description config("Configuration");
244  config.add_options()
245  ("configurable-module",
246  po::value<string>()->default_value("AthenaCommon"),
247  "Name of the module holding the configurable classes")
248  ("configurable-default-name",
249  po::value<string>()->default_value("Configurable.DefaultName"),
250  "Default name for the configurable instance")
251  ("configurable-algorithm",
252  po::value<string>()->default_value("ConfigurableAlgorithm"),
253  "Name of the configurable base class for Algorithm components")
254  ("configurable-algtool",
255  po::value<string>()->default_value("ConfigurableAlgTool"),
256  "Name of the configurable base class for AlgTool components")
257  ("configurable-auditor",
258  po::value<string>()->default_value("ConfigurableAuditor"),
259  "Name of the configurable base class for Auditor components")
260  ("configurable-service",
261  po::value<string>()->default_value("ConfigurableService"),
262  "Name of the configurable base class for Service components")
263  ;
264 
265  po::options_description cmdline_options;
266  cmdline_options.add(generic).add(config);
267 
268  po::options_description config_file_options;
269  config_file_options.add(config);
270 
271  po::options_description visible("Allowed options");
272  visible.add(generic).add(config);
273 
274  po::variables_map vm;
275 
276  try {
277  po::store( po::command_line_parser(argc, argv).
278  options(cmdline_options).run(),
279  vm );
280 
281  po::notify(vm);
282 
283  // try to read configuration from the optionally given configuration file
284  if( vm.count("input-cfg") ) {
285  string cfgFileName = vm["input-cfg"].as<string>();
286  cfgFileName = fs::system_complete( fs::path( cfgFileName ) ).string();
287  std::ifstream ifs( cfgFileName.c_str() );
288  po::store( parse_config_file( ifs, config_file_options ), vm );
289  }
290 
291  po::notify(vm);
292  }
293  catch ( po::error& err ) {
294  cout << "ERROR: error detected while parsing command options: "<< err.what() << endl;
295  return EXIT_FAILURE;
296  }
297 
298  //--- Process command options -----------------------------------------------
299  if( vm.count("help")) {
300  cout << visible << endl;
301  return EXIT_FAILURE;
302  }
303 
304  if( vm.count("package-name") ) {
305  pkgName = vm["package-name"].as<string>();
306  }
307  else {
308  cout << "ERROR: 'package-name' required" << endl;
309  cout << visible << endl;
310  return EXIT_FAILURE;
311  }
312 
313  if( vm.count("user-module") ) {
314  userModule = vm["user-module"].as<string>();
315  cout << "INFO: will import user module " << userModule << endl;
316  }
317 
318  if( vm.count("input-libraries") ) {
319  // re-shape the input arguments:
320  // - removes spurious spaces,
321  // - split into tokens.
322  Strings_t inputLibs;
323  {
324  string tmp = vm["input-libraries"].as<string>();
325  boost::trim(tmp);
326  boost::split( inputLibs, tmp,
327  boost::is_any_of(" "),
328  boost::token_compress_on );
329  }
330 
331  //
332  libs.reserve( inputLibs.size() );
333  for ( Strings_t::const_iterator iLib = inputLibs.begin();
334  iLib != inputLibs.end();
335  ++iLib ) {
336  std::string lib = fs::path(*iLib).stem().string();
337  if ( 0 == lib.find("lib") ) {
338  lib = lib.substr(3); // For *NIX remove "lib"
339  }
340  // remove duplicates
341  if ( !lib.empty() &&
342  std::find( libs.begin(), libs.end(), lib ) == libs.end() ) {
343  libs.push_back( lib );
344  }
345  } //> end loop over input-libraries
346  if ( libs.empty() ) {
347  cout << "ERROR: input component library(ies) required !\n"
348  << "ERROR: 'input-libraries' argument was ["
349  << vm["input-libraries"].as<string>()
350  << "]"
351  << endl;
352  return EXIT_FAILURE;
353  }
354  }
355  else {
356  cout << "ERROR: input component library(ies) required" << endl;
357  cout << visible << endl;
358  return EXIT_FAILURE;
359  }
360 
361  if( vm.count("output-dir") ) {
362  out = fs::system_complete( fs::path( vm["output-dir"].as<string>() ) );
363  }
364 
365  if ( vm.count("debug-level") ) {
366  Gaudi::PluginService::SetDebug( vm["debug-level"].as<int>() );
367  }
368 
369  if ( vm.count("load-library") ) {
370  Strings_t lLib_list = vm["load-library"].as< Strings_t >();
371  for (Strings_t::const_iterator lLib=lLib_list.begin();
372  lLib != lLib_list.end();
373  ++lLib) {
374  // load done through Gaudi helper class
375  System::ImageHandle tmp; // we ignore the library handle
376  unsigned long err = System::loadDynamicLib(*lLib, &tmp);
377  if (err != 1) {
378  cout << "WARNING: failed to load: "<< *lLib << endl;
379  }
380  }
381  }
382 
383 
384  if ( !fs::exists( out ) ) {
385  try {
386  fs::create_directory(out);
387  }
388  catch ( fs::filesystem_error &err ) {
389  cout << "ERROR: error creating directory: "<< err.what() << endl;
390  return EXIT_FAILURE;
391  }
392  }
393 
394  cout << ":::::: libraries : [ ";
395  copy( libs.begin(), libs.end(), ostream_iterator<string>(cout, " ") );
396  cout << "] ::::::" << endl;
397 
398  configGenerator py( pkgName, out.string() );
399  py.setConfigurableModule (vm["configurable-module"].as<string>());
400  py.setConfigurableDefaultName(vm["configurable-default-name"].as<string>());
401  py.setConfigurableAlgorithm (vm["configurable-algorithm"].as<string>());
402  py.setConfigurableAlgTool (vm["configurable-algtool"].as<string>());
403  py.setConfigurableAuditor (vm["configurable-auditor"].as<string>());
404  py.setConfigurableService (vm["configurable-service"].as<string>());
405 
406  int sc = EXIT_FAILURE;
407  try {
408  sc = py.genConfig( libs, userModule );
409  }
410  catch ( exception& e ) {
411  cout << "ERROR: Could not generate Configurable(s) !\n"
412  << "ERROR: Got exception: " << e.what() << endl;
413  return EXIT_FAILURE;
414  }
415 
416  if ( EXIT_SUCCESS == sc && ! vm.count("no-init")) {
417  // create an empty __init__.py file in the output dir
418  fstream initPy( ( out / fs::path( "__init__.py" ) ).string().c_str(),
419  std::ios_base::out|std::ios_base::trunc );
420  initPy << "## Hook for " << pkgName << " genConf module\n" << flush;
421  }
422 
423  cout << ":::::: libraries : [ ";
424  copy( libs.begin(), libs.end(), ostream_iterator<string>(cout, " ") );
425  cout << "] :::::: [DONE]" << endl;
426 
427  return sc;
428 }
429 
430 //-----------------------------------------------------------------------------
431 int configGenerator::genConfig( const Strings_t& libs, const string& userModule )
432 //-----------------------------------------------------------------------------
433 {
434  //--- Disable checking StatusCode -------------------------------------------
436 
437  const Strings_t::const_iterator endLib = libs.end();
438 
439  const std::string gaudiSvc = "GaudiCoreSvc";
440  const bool isGaudiSvc = ( std::find( libs.begin(), endLib, gaudiSvc ) != endLib );
441 
442  //--- Instantiate ApplicationMgr --------------------------------------------
443  if ( !isGaudiSvc && createAppMgr() ) {
444  cout << "ERROR: ApplicationMgr can not be created. Check environment" << endl;
445  return EXIT_FAILURE;
446  }
447 
448  //--- Iterate over component factories --------------------------------------
450  Registry& registry = Registry::instance();
451 
452  std::set<std::string> bkgNames = registry.loadedFactories();
453 
454  ISvcLocator* svcLoc = Gaudi::svcLocator();
455  IInterface* dummySvc = new Service( "DummySvc", svcLoc );
456  dummySvc->addRef();
457 
458  bool allGood = true;
459 
460  // iterate over all the requested libraries
461  for ( Strings_t::const_iterator iLib=libs.begin(); iLib != endLib; ++iLib ) {
462 
463  std::cout << ":::: processing library: " << *iLib << "..." << std::endl;
464 
465  // reset state
466  m_importGaudiHandles = false;
467  m_pyBuf.str("");
468  m_dbBuf.str("");
469 
470  //--- Load component library ----------------------------------------------
471  System::ImageHandle handle;
472  unsigned long err = System::loadDynamicLib( *iLib, &handle );
473  if ( err != 1 ) {
474  cout << "ERROR: " << System::getLastErrorString() << endl;
475  allGood = false;
476  continue;
477  }
478 
479  std::set<std::string> factories = registry.loadedFactories();
480 
481  for ( std::set<std::string>::iterator it = factories.begin();
482  it != factories.end(); ++it ) {
483  const string ident = *it;
484  if ( bkgNames.find(ident) != bkgNames.end() ) {
486  cout << "\t==> skipping [" << ident << "]..." << endl;
487  }
488  continue;
489  }
490 
491  const Registry::FactoryInfo info = registry.getInfo(*it);
492  const string rtype = info.rtype;
493 
494  // do not generate configurables for the Reflex-compatible aliases
495  if (info.properties.find("ReflexName") != info.properties.end())
496  continue;
497 
498  // Atlas contributed code (patch #1247)
499  // Skip the generation of configurables if the component does not come
500  // from the same library we are processing (i.e. we found a symbol that
501  // is coming from a library loaded by the linker).
502  if ( !DsoUtils::inDso( info.ptr, DsoUtils::libNativeName(*iLib) ) ) {
503  cout << "WARNING: library [" << *iLib << "] exposes factory ["
504  << ident << "] which is declared in ["
505  << DsoUtils::dsoName(info.ptr) << "] !!" << endl;
506  continue;
507  }
508 
509  string type;
510  bool known = true;
511  if ( ident == "ApplicationMgr" ) type = "ApplicationMgr";
512  else if ( rtype == typeid(IInterface*).name() ) type = "IInterface";
513  else if ( rtype == typeid(IAlgorithm*).name() ) type = "Algorithm";
514  else if ( rtype == typeid(IService* ).name() ) type = "Service";
515  else if ( rtype == typeid(IAlgTool* ).name() ) type = "AlgTool";
516  else if ( rtype == typeid(IAuditor* ).name() ) type = "Auditor";
517  else if ( rtype == typeid(IConverter*).name() ) type = "Converter";
518  else if ( rtype == typeid(DataObject*).name() ) type = "DataObject";
519  else type = "Unknown", known = false;
520  string name = ident;
521  // handle possible problems with templated components
522  boost::trim(name);
523 
524  if ( type == "IInterface" ) {
527  continue;
528  }
529 
530  if ( type == "Converter" || type == "DataObject" ) {
532  continue;
533  }
534 
535  if ( !known ) {
536  cout << "WARNING: Unknown (return) type [" << System::typeinfoName(rtype.c_str()) << "] !!"
537  << " Component [" << ident << "] is skipped !"
538  << endl;
539  continue;
540  }
541 
542  cout << " - component: " << info.className << " (";
543  if (info.className != name)
544  cout << name << ": ";
545  cout << type << ")" << endl;
546 
547  string cname = "DefaultName";
548  SmartIF<IProperty> prop;
549  try {
550  if ( type == "Algorithm" ) {
551  prop = SmartIF<IAlgorithm>(Algorithm::Factory::create(ident, cname, svcLoc));
552  }
553  else if ( type == "Service") {
554  prop = SmartIF<IService>(Service::Factory::create(ident, cname, svcLoc));
555  }
556  else if ( type == "AlgTool") {
557  prop = SmartIF<IAlgTool>(AlgTool::Factory::create(ident, cname, type, dummySvc));
558  // FIXME: AlgTool base class increase artificially by 1 the refcount.
559  prop->release();
560  }
561  else if ( type == "Auditor") {
562  prop = SmartIF<IAuditor>(Auditor::Factory::create(ident, cname, svcLoc));
563  }
564  else if ( type == "ApplicationMgr") {
565  prop = SmartIF<ISvcLocator>(svcLoc);
566  }
567  else {
568  continue; // unknown
569  }
570  }
571  catch ( exception& e ) {
572  cout << "ERROR: Error instantiating " << name
573  << " from " << *iLib << endl;
574  cout << "ERROR: Got exception: " << e.what() << endl;
575  allGood = false;
576  continue;
577  }
578  catch ( ... ) {
579  cout << "ERROR: Error instantiating " << name
580  << " from " << *iLib << endl;
581  allGood = false;
582  continue;
583  }
584  if( prop ) {
585  if (genComponent( *iLib, name, type, prop->getProperties() )) {
586  allGood = false;
587  }
588  prop.reset();
589  } else {
590  cout << "ERROR: could not cast IInterface* object to an IProperty* !\n"
591  << "ERROR: return type from PluginSvc is [" << rtype << "]...\n"
592  << "ERROR: NO Configurable will be generated for ["
593  << name << "] !"
594  << endl;
595  allGood = false;
596  }
597  } //> end loop over factories
598 
602  const std::string pyName = ( fs::path(m_outputDirName) /
603  fs::path(*iLib+"Conf.py") ).string();
604  const std::string dbName = ( fs::path(m_outputDirName) /
605  fs::path(*iLib+".confdb") ).string();
606 
607  std::fstream py( pyName.c_str(),
608  std::ios_base::out|std::ios_base::trunc );
609  std::fstream db( dbName.c_str(),
610  std::ios_base::out|std::ios_base::trunc );
611 
612  genHeader ( py, db );
613  if (!userModule.empty())
614  py << "from " << userModule << " import *" <<endl;
615  genBody ( py, db );
616  genTrailer( py, db );
617 
618  } //> end loop over libraries
619 
620  dummySvc->release();
621  dummySvc = 0;
622 
623  return allGood ? EXIT_SUCCESS : EXIT_FAILURE;
624 }
625 
626 void configGenerator::genImport( std::ostream& s,
627  const boost::format& frmt,
628  std::string indent = ""){
629 
630  std::string::size_type pos = 0, nxtpos = 0;
631  std::string mod;
632 
633  while ( std::string::npos != pos ){
634  // find end of module name
635  nxtpos = m_configurable["Module"].find_first_of(',',pos);
636 
637  // Prepare import string
638  mod = m_configurable["Module"].substr(pos,nxtpos-pos);
639  std::ostringstream import;
640  import << boost::format(frmt) % mod;
641 
642  // append a normal import or a try/except enclosed one depending
643  // on availability of a fall-back module (next in the list)
644  if ( std::string::npos == nxtpos ) {
645  // last possible module
646  s << indent << import.str() << "\n" << flush;
647  pos = std::string::npos;
648  } else {
649  // we have a fallback for this
650  s << indent << "try:\n"
651  << indent << py_tab << import.str() << "\n"
652  << indent << "except ImportError:\n"
653  << flush;
654  pos = nxtpos+1;
655  }
656  // increase indentation level for next iteration
657  indent += py_tab;
658  }
659 }
660 
661 //-----------------------------------------------------------------------------
662 void configGenerator::genHeader( std::ostream& py,
663  std::ostream& db )
664 //-----------------------------------------------------------------------------
665 {
666  // python file part
667  std::string now = Gaudi::Time::current().format(true);
668  py << "#" << now //<< "\n"
669  << "\"\"\"Automatically generated. DO NOT EDIT please\"\"\"\n";
670  if ( m_importGaudiHandles ) {
671  py << "from GaudiKernel.GaudiHandles import *\n";
672  }
673 
674  genImport(py,boost::format("from %1%.Configurable import *"));
675 
676  // db file part
677  db << "## -*- ascii -*- \n"
678  << "# db file automatically generated by genconf on: "
679  << now
680  << "\n"
681  << flush;
682 }
683 //-----------------------------------------------------------------------------
684 void configGenerator::genTrailer( std::ostream& /*py*/,
685  std::ostream& db )
686 //-----------------------------------------------------------------------------
687 {
688  // db file part
689  db << "## " << m_pkgName << "\n"
690  << std::flush;
691 }
692 
693 //-----------------------------------------------------------------------------
694 int
695 configGenerator::genComponent( const std::string& libName,
696  const std::string& componentName,
697  const std::string& componentType,
698  const vector<Property*>& properties )
699 //-----------------------------------------------------------------------------
700 {
701  string cname = componentName;
702  pythonizeName(cname);
703 
704  typedef GaudiUtils::HashMap<std::string, std::string> PropertyDoc_t;
705  PropertyDoc_t propDoc;
706 
707  m_pyBuf << "\n";
708  m_pyBuf << "class " << cname
709  << "( " << m_configurable[componentType] << " ) :"
710  << "\n";
711  m_pyBuf << " __slots__ = { \n";
712  for ( vector<Property*>::const_iterator it = properties.begin() ;
713  it != properties.end(); ++it ) {
714 
715  const string pname = (*it)->name();
716  // Validate property name (it must be a valid Python identifier)
717  if (!boost::regex_match(pname, pythonIdentifier)) {
718  std::cout << "ERROR: invalid property name \"" << pname
719  << "\" in component " << cname
720  << " (invalid Python identifier)" << std::endl;
721  // try to make the buffer at least more or less valid python code.
722  m_pyBuf << " #ERROR-invalid identifier '" << pname << "'\n"
723  << " }\n";
724  return 1;
725  }
726 
727  string pvalue, ptype;
728  pythonizeValue( (*it), pvalue, ptype );
729  m_pyBuf << " '" << pname << "' : " << pvalue <<", # " << ptype << "\n";
730 
731  if ( (*it)->documentation() != "none" ) {
732  propDoc[pname] = (*it)->documentation();
733  }
734 
735  }
736  m_pyBuf << " }\n";
737  m_pyBuf << " _propertyDocDct = { \n";
738  for ( PropertyDoc_t::const_iterator iProp = propDoc.begin();
739  iProp != propDoc.end();
740  ++iProp ) {
741  m_pyBuf << std::setw(5)
742  << "'" << iProp->first << "' : "
743  << "\"\"\" " << iProp->second << " \"\"\",\n";
744  }
745  m_pyBuf << " }\n";
746 
747  m_pyBuf
748  << " def __init__(self, name = " << m_configurable["DefaultName"]
749  << ", **kwargs):\n"
750  << " super(" << cname << ", self).__init__(name)\n"
751  << " for n,v in kwargs.items():\n"
752  << " setattr(self, n, v)\n"
753  << " def getDlls( self ):\n"
754  << " return '" << libName << "'\n"
755  << " def getType( self ):\n"
756  << " return '" << componentName << "'\n"
757  << " pass # class " << cname << "\n"
758  << flush;
759 
760  // name of the auto-generated module
761  const string pyName = ( fs::path(m_outputDirName) /
762  fs::path(libName+"Conf.py") ).string();
763  const string modName = fs::basename( fs::path( pyName ).leaf() );
764 
765  // now the db part
766  m_dbBuf
767  << m_pkgName << "." << modName << " "
768  << libName << " " << cname
769  << "\n"
770  << flush;
771 
772  return 0;
773 }
774 //-----------------------------------------------------------------------------
775 void configGenerator::pythonizeName( string& name )
776 //-----------------------------------------------------------------------------
777 {
778  static string in("<>&*,: ().");
779  static string out("__rp__s___");
780  boost::algorithm::replace_all(name, ", ", ",");
781  for ( string::iterator i = name.begin(); i != name.end(); ++i ) {
782  if ( in.find(*i) != string::npos ) *i = out[in.find(*i)];
783  }
784 }
785 
786 //-----------------------------------------------------------------------------
788  string& pvalue, string& ptype )
789 //-----------------------------------------------------------------------------
790 {
791  const std::string cvalue = p->toString();
792  const type_info& ti = *p->type_info();
793  if ( ti == typeid(bool) ) {
794  pvalue = ( cvalue == "0" || cvalue == "False" || cvalue == "false" )
795  ? "False"
796  : "True";
797  ptype = "bool";
798  }
799  else if ( ti == typeid(char) || ti == typeid(signed char)
800  || ti == typeid(unsigned char) ||
801  ti == typeid(short) || ti == typeid(unsigned short) ||
802  ti == typeid(int) || ti == typeid(unsigned int) ||
803  ti == typeid(long) || ti == typeid(unsigned long) ) {
804  pvalue = cvalue;
805  ptype = "int";
806  }
807  else if ( ti == typeid(long long) || ti == typeid(unsigned long long) ) {
808  pvalue = cvalue + "L";
809  ptype = "long";
810  }
811  else if ( ti == typeid(float) || ti == typeid(double) ) {
812  // forces python to handle this as a float: put a dot in there...
813  pvalue = boost::to_lower_copy(cvalue);
814  if ( pvalue == "nan" ) {
815  pvalue = "float('nan')";
816  std::cout << "WARNING: default value for ["
817  << p->name() << "] is NaN !!"
818  << std::endl;
819  } else if ( std::string::npos == pvalue.find(".") &&
820  std::string::npos == pvalue.find("e") ) {
821  pvalue = cvalue + ".0";
822  }
823  ptype = "float";
824  }
825  else if ( ti == typeid(string) ) {
826 
827  pvalue = "'"+cvalue+"'";
828  ptype = "str";
829  }
830  else if ( ti == typeid(GaudiHandleBase) ) {
831  m_importGaudiHandles = true;
832  const GaudiHandleProperty& hdl
833  = dynamic_cast<const GaudiHandleProperty&>(*p);
834  const GaudiHandleBase& base = hdl.value();
835 
836  pvalue = base.pythonRepr();
837  ptype = "GaudiHandle";
838  }
839  else if ( ti == typeid(GaudiHandleArrayBase) ) {
840  m_importGaudiHandles = true;
841  const GaudiHandleArrayProperty& hdl
842  = dynamic_cast<const GaudiHandleArrayProperty&>(*p);
843  const GaudiHandleArrayBase& base = hdl.value();
844 
845  pvalue = base.pythonRepr();
846  ptype = "GaudiHandleArray";
847  }
848  else {
849  std::ostringstream v_str;
850  v_str.setf(std::ios::fixed); // to correctly display floats
851  p->toStream(v_str);
852  pvalue = v_str.str();
853  ptype = "list";
854  }
855 }
856 
857 //-----------------------------------------------------------------------------
859 //-----------------------------------------------------------------------------
860 {
862  SmartIF<IProperty> propMgr ( iface );
863  SmartIF<IAppMgrUI> appUI ( iface );
864 
865  if ( propMgr.isValid() && appUI.isValid() ) {
866  propMgr->setProperty( "JobOptionsType", "NONE" ); // No job options
867  propMgr->setProperty( "AppName", ""); // No initial printout message
868  propMgr->setProperty( "OutputLevel", "7"); // No other printout messages
869  appUI->configure();
870  return EXIT_SUCCESS;
871  }
872  else {
873  return EXIT_FAILURE;
874  }
875 }
const GaudiHandleArrayBase & value() const
Definition: Property.h:917
int genConfig(const Strings_t &modules, const string &userModule)
main entry point of this class:
Definition: genconf.cpp:431
GAUDI_API long argc()
Number of arguments passed to the commandline (==numCmdLineArgs()); just to match argv call...
Definition: System.cpp:526
The ISvcLocator is the interface implemented by the Service Factory in the Application Manager to loc...
Definition: ISvcLocator.h:26
The data converters are responsible to translate data from one representation into another...
Definition: IConverter.h:57
GAUDI_API std::string format(const char *,...)
MsgStream format utility "a la sprintf(...)".
Definition: MsgStream.cpp:133
virtual std::string toString() const =0
value -> string
std::vector< std::string > Strings_t
Definition: genconf.cpp:77
const std::string & name() const
property name
Definition: Property.h:47
-*- C++ -*- /////////////////////////////
GAUDI_API const std::string typeinfoName(const std::type_info &)
Get platform independent information about the class type.
Definition: System.cpp:298
int genComponent(const std::string &libName, const std::string &componentName, const std::string &componentType, const vector< Property * > &properties)
Definition: genconf.cpp:695
void pythonizeValue(const Property *prop, string &pvalue, string &ptype)
handle the "marshalling" of Properties
Definition: genconf.cpp:787
static Time current(void)
Returns the current time.
Definition: Time.cpp:114
list argv
Definition: gaudirun.py:192
void pythonizeName(string &name)
Translates a valid C++ typename into a valid python one.
Definition: genconf.cpp:775
void setConfigurableDefaultName(const std::string &defaultName)
customize the default name for configurable instances
Definition: genconf.cpp:144
std::vector< fs::path > LibPathNames_t
Definition: genconf.cpp:81
void setConfigurableAlgTool(const std::string &cfgAlgTool)
customize the configurable base class for AlgTool component
Definition: genconf.cpp:156
void * ImageHandle
Definition of an image handle.
Definition: ModuleInfo.h:30
GaudiUtils::HashMap< std::string, std::string > m_configurable
Configurable customization.
Definition: genconf.cpp:118
stringstream m_pyBuf
buffer of auto-generated configurables
Definition: genconf.cpp:101
GAUDIPS_API Logger & logger()
Return the current logger instance.
void setConfigurableModule(const std::string &moduleName)
customize the Module name where configurable base classes are defined
Definition: genconf.cpp:138
GAUDIPS_API void SetDebug(int debugLevel)
Backward compatibility with Reflex.
int main(int argc, char **argv)
Definition: genconf.cpp:201
string type
Definition: gaudirun.py:126
GAUDI_API ISvcLocator * svcLocator()
bool isValid() const
Allow for check if smart pointer is valid.
Definition: SmartIF.h:51
General service interface definition.
Definition: IService.h:19
Definition of the basic interface.
Definition: IInterface.h:160
virtual const std::string pythonRepr() const
Python representation of handle, i.e.
Definition: GaudiHandle.cpp:56
void genHeader(std::ostream &pyOut, std::ostream &dbOut)
Definition: genconf.cpp:662
list options
Definition: gaudirun.py:346
stringstream m_dbBuf
buffer of generated configurables informations for the "Db" file The "Db" file is holding information...
Definition: genconf.cpp:111
configGenerator(const string &pkgName, const string &outputDirName)
Definition: genconf.cpp:121
The IAlgorithm is the interface implemented by the Algorithm base class.
Definition: IAlgorithm.h:20
void setConfigurableAlgorithm(const std::string &cfgAlgorithm)
customize the configurable base class for Algorithm component
Definition: genconf.cpp:150
GAUDI_API std::string path(const AIDA::IBaseHistogram *aida)
get the path in THS for AIDA histogram
Base class of array's of various gaudihandles.
Definition: GaudiHandle.h:293
string m_outputDirName
absolute path to the directory where genconf will store auto-generated files (Configurables and Confi...
Definition: genconf.cpp:98
Property base class allowing Property* collections to be "homogeneous".
Definition: Property.h:43
virtual unsigned long release()=0
Release Interface instance.
void genImport(std::ostream &s, const boost::format &frmt, std::string indent)
Definition: genconf.cpp:626
bool m_importGaudiHandles
switch to decide if the generated configurables need to import GaudiHandles (ie: if one of the compon...
Definition: genconf.cpp:105
void setConfigurableService(const std::string &cfgService)
customize the configurable base class for Service component
Definition: genconf.cpp:168
GAUDI_API const std::string & moduleName()
Get the name of the (executable/DLL) file without file-type.
Definition: ModuleInfo.cpp:55
The interface implemented by the AlgTool base class.
Definition: IAlgTool.h:23
const GaudiHandleBase & value() const
Definition: Property.h:857
string s
Definition: gaudirun.py:210
In-memory database of the loaded factories.
string m_pkgName
name of the package we are processing
Definition: genconf.cpp:94
virtual unsigned long addRef()=0
Increment the reference count of Interface instance.
static GAUDI_API void disableChecking()
Definition: StatusCode.cpp:23
const std::type_info * type_info() const
property type-info
Definition: Property.h:51
void genTrailer(std::ostream &pyOut, std::ostream &dbOut)
Definition: genconf.cpp:684
GAUDI_API const std::string getLastErrorString()
Get last system error as string.
Definition: System.cpp:253
Base class to handles to be used in lieu of naked pointers to various Gaudi components.
Definition: GaudiHandle.h:80
Base class for all services.
Definition: Service.h:33
A DataObject is the base class of any identifiable object on any data store.
Definition: DataObject.h:31
list i
Definition: ana.py:128
int createAppMgr()
Definition: genconf.cpp:858
The IAuditor is the interface implmented by the AlgAuditor base class.
Definition: IAuditor.h:18
void reset(TYPE *ptr=0)
Set the internal pointer to the passed one disposing of the old one.
Definition: SmartIF.h:74
virtual const std::string pythonRepr() const
Python representation of array of handles, i.e.
Definition: GaudiHandle.cpp:99
std::string libNativeName(const std::string &libName)
Definition: DsoUtils.h:18
void genBody(std::ostream &pyOut, std::ostream &dbOut)
Definition: genconf.cpp:181
std::string format(bool local, std::string spec="%c") const
Format the time using strftime.
Definition: Time.cpp:280
GAUDI_API IAppMgrUI * createApplicationMgr(const std::string &dllname, const std::string &factname)
virtual void toStream(std::ostream &out) const =0
value -> stream
GAUDI_API unsigned long loadDynamicLib(const std::string &name, ImageHandle *handle)
Load dynamic link library.
Definition: System.cpp:123
void setConfigurableAuditor(const std::string &cfgAuditor)
customize the configurable base class for AlgTool component
Definition: genconf.cpp:162