00001
00002
00003 #ifdef _WIN32
00004
00005
00006 #pragma warning ( disable : 4273 )
00007
00008
00009 #define NOMSG
00010 #define NOGDI
00011 #endif
00012
00013
00014 #include "boost/program_options.hpp"
00015 #include "boost/filesystem/operations.hpp"
00016 #include "boost/filesystem/exception.hpp"
00017 #include "boost/filesystem/convenience.hpp"
00018 #include "boost/algorithm/string/split.hpp"
00019 #include "boost/algorithm/string/classification.hpp"
00020 #include "boost/algorithm/string/trim.hpp"
00021 #include "boost/algorithm/string/case_conv.hpp"
00022 #include "boost/format.hpp"
00023
00024 #include "GaudiKernel/System.h"
00025 #include "GaudiKernel/ISvcLocator.h"
00026 #include "GaudiKernel/IProperty.h"
00027 #include "GaudiKernel/IAppMgrUI.h"
00028 #include "GaudiKernel/IAlgorithm.h"
00029 #include "GaudiKernel/IAlgTool.h"
00030 #include "GaudiKernel/IAuditor.h"
00031 #include "GaudiKernel/IAppMgrUI.h"
00032 #include "GaudiKernel/Service.h"
00033 #include "GaudiKernel/Bootstrap.h"
00034 #include "GaudiKernel/SmartIF.h"
00035 #include "GaudiKernel/HashMap.h"
00036 #include "GaudiKernel/GaudiHandle.h"
00037
00038 #include "Reflex/PluginService.h"
00039 #include "Reflex/Reflex.h"
00040 #include "Reflex/SharedLibrary.h"
00041
00042 #include "RVersion.h"
00043
00044 #include <algorithm>
00045 #include <iostream>
00046 #include <fstream>
00047 #include <sstream>
00048 #include <exception>
00049 #include <ctime>
00050 #include <set>
00051 #include <vector>
00052
00053
00054 #include "DsoUtils.h"
00055
00056
00057
00058 namespace po = boost::program_options;
00059 namespace fs = boost::filesystem;
00060
00061 using namespace std;
00062 using namespace ROOT::Reflex;
00063
00064
00065 typedef std::vector<std::string> Strings_t;
00066 typedef std::vector<fs::path> LibPathNames_t;
00067
00068 namespace {
00069 const std::string py_tab = " ";
00070 }
00071
00072 class configGenerator
00073 {
00075 string m_pkgName;
00076
00079 string m_outputDirName;
00080
00082 stringstream m_pyBuf;
00083
00086 bool m_importGaudiHandles;
00087
00092 stringstream m_dbBuf;
00093
00099 GaudiUtils::HashMap<std::string, std::string> m_configurable;
00100
00101 public:
00102 configGenerator( const string& pkgName,
00103 const string& outputDirName ) :
00104 m_pkgName ( pkgName ),
00105 m_outputDirName ( outputDirName ),
00106 m_pyBuf ( ),
00107 m_importGaudiHandles( false ),
00108 m_dbBuf ( ),
00109 m_configurable ( )
00110 {}
00111
00116 int genConfig( const Strings_t& modules );
00117
00119 void setConfigurableModule( const std::string& moduleName )
00120 {
00121 m_configurable[ "Module" ] = moduleName;
00122 }
00123
00125 void setConfigurableDefaultName( const std::string& defaultName )
00126 {
00127 m_configurable[ "DefaultName" ] = defaultName;
00128 }
00129
00131 void setConfigurableAlgorithm( const std::string& cfgAlgorithm )
00132 {
00133 m_configurable[ "Algorithm" ] = cfgAlgorithm;
00134 }
00135
00137 void setConfigurableAlgTool( const std::string& cfgAlgTool )
00138 {
00139 m_configurable[ "AlgTool" ] = cfgAlgTool;
00140 }
00141
00143 void setConfigurableAuditor( const std::string& cfgAuditor )
00144 {
00145 m_configurable[ "Auditor" ] = cfgAuditor;
00146 }
00147
00149 void setConfigurableService( const std::string& cfgService )
00150 {
00151 m_configurable[ "Service" ] = cfgService;
00152 m_configurable[ "ApplicationMgr" ] = cfgService;
00153 }
00154
00155 private:
00156 void genComponent( const std::string& libName,
00157 const std::string& componentName,
00158 const std::string& componentType,
00159 const vector<Property*>& properties );
00160 void genImport( std::ostream& s, const boost::format& frmt,std::string indent);
00161 void genHeader( std::ostream& pyOut, std::ostream& dbOut );
00162 void genBody( std::ostream& pyOut,
00163 std::ostream& dbOut ) {
00164 pyOut << m_pyBuf.str() << flush;
00165 dbOut << m_dbBuf.str() << flush;
00166 }
00167 void genTrailer( std::ostream& pyOut,
00168 std::ostream& dbOut );
00169
00171 void pythonizeValue( const Property* prop,
00172 string& pvalue,
00173 string& ptype );
00174
00176 void pythonizeName( string& name );
00177 };
00178
00179 int createAppMgr();
00180
00181
00182 int main ( int argc, char** argv )
00183
00184 {
00185 fs::path::default_name_check(fs::native);
00186 fs::path pwd = fs::initial_path();
00187 fs::path out;
00188 Strings_t libs;
00189 std::string pkgName;
00190
00191
00192 po::options_description generic("Generic options");
00193 generic.add_options()
00194 ("help,h",
00195 "produce this help message")
00196 ("package-name,p",
00197 po::value<string>(),
00198 "name of the package for which we create the configurables file")
00199 ("input-libraries,i",
00200 po::value<string>(),
00201 "libraries to extract the component configurables from")
00202 ("input-cfg,c",
00203 po::value<string>(),
00204 "path to the cfg file holding the description of the Configurable base "
00205 "classes, the python module holding the Configurable definitions, etc...")
00206 ("output-dir,o",
00207 po::value<string>()->default_value("../genConf"),
00208 "output directory for genconf files.")
00209 ("debug-level,d",
00210 po::value<int>()->default_value(0),
00211 "debug level")
00212 ("load-library,l",
00213 po::value< Strings_t >()->composing(),
00214 "preloading library")
00215 ;
00216
00217
00218
00219 po::options_description config("Configuration");
00220 config.add_options()
00221 ("configurable-module",
00222 po::value<string>()->default_value("AthenaCommon"),
00223 "Name of the module holding the configurable classes")
00224 ("configurable-default-name",
00225 po::value<string>()->default_value("Configurable.DefaultName"),
00226 "Default name for the configurable instance")
00227 ("configurable-algorithm",
00228 po::value<string>()->default_value("ConfigurableAlgorithm"),
00229 "Name of the configurable base class for Algorithm components")
00230 ("configurable-algtool",
00231 po::value<string>()->default_value("ConfigurableAlgTool"),
00232 "Name of the configurable base class for AlgTool components")
00233 ("configurable-auditor",
00234 po::value<string>()->default_value("ConfigurableAuditor"),
00235 "Name of the configurable base class for Auditor components")
00236 ("configurable-service",
00237 po::value<string>()->default_value("ConfigurableService"),
00238 "Name of the configurable base class for Service components")
00239 ;
00240
00241 po::options_description cmdline_options;
00242 cmdline_options.add(generic).add(config);
00243
00244 po::options_description config_file_options;
00245 config_file_options.add(config);
00246
00247 po::options_description visible("Allowed options");
00248 visible.add(generic).add(config);
00249
00250 po::variables_map vm;
00251
00252 try {
00253 po::store( po::command_line_parser(argc, argv).
00254 options(cmdline_options).run(),
00255 vm );
00256
00257 po::notify(vm);
00258
00259
00260 if( vm.count("input-cfg") ) {
00261 string cfgFileName = vm["input-cfg"].as<string>();
00262 cfgFileName = fs::complete( fs::path( cfgFileName,
00263 fs::native ) ).string();
00264 std::ifstream ifs( cfgFileName.c_str() );
00265 po::store( parse_config_file( ifs, config_file_options ), vm );
00266 }
00267
00268 po::notify(vm);
00269 }
00270 catch ( po::error& err ) {
00271 cout << "ERR0R: error detected while parsing command options: "<< err.what() << endl;
00272 return EXIT_FAILURE;
00273 }
00274
00275
00276 if( vm.count("help")) {
00277 cout << visible << endl;
00278 return EXIT_FAILURE;
00279 }
00280
00281 if( vm.count("package-name") ) {
00282 pkgName = vm["package-name"].as<string>();
00283 }
00284 else {
00285 cout << "ERROR: 'package-name' required" << endl;
00286 cout << visible << endl;
00287 return EXIT_FAILURE;
00288 }
00289
00290 if( vm.count("input-libraries") ) {
00291
00292
00293
00294 Strings_t inputLibs;
00295 {
00296 string tmp = vm["input-libraries"].as<string>();
00297 boost::trim(tmp);
00298 boost::split( inputLibs, tmp,
00299 boost::is_any_of(" "),
00300 boost::token_compress_on );
00301 }
00302
00303
00304 libs.reserve( inputLibs.size() );
00305 for ( Strings_t::const_iterator iLib = inputLibs.begin();
00306 iLib != inputLibs.end();
00307 ++iLib ) {
00308 fs::path libPath = fs::path( *iLib, fs::native );
00309 std::string lib = libPath.leaf().substr(0, libPath.leaf().find('.') );
00310 if ( 0 == lib.find("lib") ) {
00311 lib = lib.substr(3);
00312 }
00313
00314 if ( !lib.empty() &&
00315 std::find( libs.begin(), libs.end(), lib ) == libs.end() ) {
00316 libs.push_back( lib );
00317 }
00318 }
00319 if ( libs.empty() ) {
00320 cout << "ERROR: input component library(ies) required !\n"
00321 << "ERROR: 'input-libraries' argument was ["
00322 << vm["input-libraries"].as<string>()
00323 << "]"
00324 << endl;
00325 return EXIT_FAILURE;
00326 }
00327 }
00328 else {
00329 cout << "ERROR: input component library(ies) required" << endl;
00330 cout << visible << endl;
00331 return EXIT_FAILURE;
00332 }
00333
00334 if( vm.count("output-dir") ) {
00335 out = fs::complete( fs::path( vm["output-dir"].as<string>(),
00336 fs::native ) );
00337 }
00338
00339 if ( vm.count("debug-level") ) {
00340 PluginService::SetDebug( vm["debug-level"].as<int>() );
00341 }
00342
00343 if ( vm.count("load-library") ) {
00344 Strings_t lLib_list = vm["load-library"].as< Strings_t >();
00345 for (Strings_t::const_iterator lLib=lLib_list.begin();
00346 lLib != lLib_list.end();
00347 ++lLib) {
00348
00349 SharedLibrary tmplib(*lLib) ;
00350 tmplib.Load() ;
00351 }
00352 }
00353
00354
00355 if ( !fs::exists( out ) ) {
00356 try {
00357 fs::create_directory(out);
00358 }
00359 catch ( fs::filesystem_error err ) {
00360 cout << "ERR0R: error creating directory: "<< err.what() << endl;
00361 return EXIT_FAILURE;
00362 }
00363 }
00364
00365 cout << ":::::: libraries : [ ";
00366 copy( libs.begin(), libs.end(), ostream_iterator<string>(cout, " ") );
00367 cout << "] ::::::" << endl;
00368
00369 configGenerator py( pkgName, out.string() );
00370 py.setConfigurableModule (vm["configurable-module"].as<string>());
00371 py.setConfigurableDefaultName(vm["configurable-default-name"].as<string>());
00372 py.setConfigurableAlgorithm (vm["configurable-algorithm"].as<string>());
00373 py.setConfigurableAlgTool (vm["configurable-algtool"].as<string>());
00374 py.setConfigurableAuditor (vm["configurable-auditor"].as<string>());
00375 py.setConfigurableService (vm["configurable-service"].as<string>());
00376
00377 int sc = EXIT_FAILURE;
00378 try {
00379 sc = py.genConfig( libs );
00380 }
00381 catch ( exception& e ) {
00382 cout << "ERROR: Could not generate Configurable(s) !\n"
00383 << "ERROR: Got exception: " << e.what() << endl;
00384 return EXIT_FAILURE;
00385 }
00386
00387 if ( EXIT_SUCCESS == sc ) {
00388
00389 fstream initPy( ( out / fs::path( "__init__.py" ) ).string().c_str(),
00390 std::ios_base::out|std::ios_base::trunc );
00391 initPy << "## Hook for " << pkgName << " genConf module\n" << flush;
00392 }
00393
00394 cout << ":::::: libraries : [ ";
00395 copy( libs.begin(), libs.end(), ostream_iterator<string>(cout, " ") );
00396 cout << "] :::::: [DONE]" << endl;
00397
00398 return sc;
00399 }
00400
00403 inline std::string getId(const Member & m) {
00404 return (m.Properties().HasProperty("id") && (m.Properties().PropertyValue("id").TypeInfo() == typeid(std::string))) ?
00405 m.Properties().PropertyAsString("id") :
00406 m.Properties().PropertyAsString("name") ;
00407 }
00408
00409 template <class T>
00410 IProperty *makeInstance(const Member &member, const vector<void*> &args)
00411 {
00412 Object dummy;
00413 T* obj;
00414 #if ROOT_VERSION_CODE < ROOT_VERSION(5,21,6)
00415 obj = static_cast<T*>(member.Invoke(dummy,args).Address());
00416 #else
00417 member.Invoke(dummy,obj,args);
00418 #endif
00419 return dynamic_cast<IProperty*>(obj);
00420 }
00421
00422
00423
00424 int configGenerator::genConfig( const Strings_t& libs )
00425
00426 {
00427
00428 StatusCode::disableChecking();
00429
00430 const Strings_t::const_iterator endLib = libs.end();
00431
00432 const std::string gaudiSvc = "GaudiSvc";
00433 const bool isGaudiSvc = ( std::find( libs.begin(), endLib, gaudiSvc ) != endLib );
00434
00435
00436 if ( !isGaudiSvc && createAppMgr() ) {
00437 cout << "ERROR: ApplicationMgr can not be created. Check environment" << endl;
00438 return EXIT_FAILURE;
00439 }
00440
00441
00442 Scope factories = Scope::ByName(PLUGINSVC_FACTORY_NS);
00443 if ( !factories ) {
00444 cout << "ERROR: No PluginSvc factory namespace could be found" << endl;
00445 return EXIT_FAILURE;
00446 }
00447
00448 ISvcLocator* svcLoc = Gaudi::svcLocator();
00449 IService* dummySvc = new Service( "DummySvc", svcLoc );
00450 dummySvc->addRef();
00451
00452 bool allGood = true;
00453
00454
00455 for ( Strings_t::const_iterator iLib=libs.begin(); iLib != endLib; ++iLib ) {
00456
00457 std::cout << ":::: processing library: " << *iLib << "..." << std::endl;
00458
00459
00460 m_importGaudiHandles = false;
00461 m_pyBuf.str("");
00462 m_dbBuf.str("");
00463
00464
00465
00466 set<string> bkgNames;
00467 if ( !isGaudiSvc ) {
00468 for ( Member_Iterator it = factories.FunctionMember_Begin();
00469 it != factories.FunctionMember_End(); ++it ) {
00470 string ident = getId(*it);
00471 if ( PluginService::Debug() > 0 ) {
00472 cout << "::: " << ident << endl;
00473 }
00474 bkgNames.insert( ident );
00475 }
00476 }
00477 const set<string>::const_iterator bkgNamesEnd = bkgNames.end();
00478
00479
00480 System::ImageHandle handle;
00481 unsigned long err = System::loadDynamicLib( *iLib, &handle );
00482 if ( err != 1 ) {
00483 cout << "ERROR: " << System::getLastErrorString() << endl;
00484 allGood = false;
00485 continue;
00486 }
00487
00488 for ( Member_Iterator it = factories.FunctionMember_Begin();
00489 it != factories.FunctionMember_End();
00490 ++it ) {
00491 const string ident = getId(*it);
00492 if ( bkgNames.find(ident) != bkgNamesEnd ) {
00493 if ( PluginService::Debug() > 0 ) {
00494 cout << "\t==> skipping [" << ident << "]..." << endl;
00495 }
00496 continue;
00497 }
00498
00499
00500
00501
00502
00503
00504 if ( !DsoUtils::inDso( *it, DsoUtils::libNativeName(*iLib) ) ) {
00505 cout << "WARNING: library [" << *iLib << "] requested factory "
00506 << "from another library ["
00507 << DsoUtils::dsoName(*it) << "]"
00508 << " ==> [" << ident << "] !!"
00509 << endl;
00510 continue;
00511 }
00512
00513 const string rtype = it->TypeOf().ReturnType().Name();
00514 string type;
00515 bool known = true;
00516 if ( ident == "ApplicationMgr" ) type = "ApplicationMgr";
00517 else if ( rtype == "IInterface*" ) type = "IInterface";
00518 else if ( rtype == "IAlgorithm*" ) type = "Algorithm";
00519 else if ( rtype == "IService*" ) type = "Service";
00520 else if ( rtype == "IAlgTool*" ) type = "AlgTool";
00521 else if ( rtype == "IAuditor*" ) type = "Auditor";
00522 else if ( rtype == "IConverter*" ) type = "Converter";
00523 else if ( rtype == "DataObject*" ) type = "DataObject";
00524 else type = "Unknown", known = false;
00525 string name = ident;
00526
00527 boost::trim(name);
00528
00529 cout << " - component: " << name << endl;
00530
00531 if ( type == "IInterface" ) {
00534 continue;
00535 }
00536
00537 if ( type == "Converter" || type == "DataObject" ) {
00539 continue;
00540 }
00541
00542
00545
00546
00547 if ( !known ) {
00548 cout << "WARNING: Unknown (return) type [" << rtype << "] !!\n"
00549 << "WARNING: component [" << ident << "] is skipped !"
00550 << endl;
00551 allGood = false;
00552 continue;
00553 }
00554
00555 string cname = "DefaultName";
00556 vector<void*> args;
00557 args.reserve( 3 );
00558 if ( type == "AlgTool" ) {
00559 args.resize( 3 );
00560 args[0] = &cname;
00561 args[1] = &type;
00562 args[2] = dummySvc;
00563 }
00564 else {
00565 args.resize( 2 );
00566 args[0] = &cname;
00567 args[1] = svcLoc;
00568 }
00569 IProperty* prop = 0;
00570 try {
00571 if ( type == "Algorithm" ) {
00572 prop = makeInstance<IAlgorithm>(*it,args);
00573 }
00574 else if ( type == "Service") {
00575 prop = makeInstance<IService>(*it,args);
00576 }
00577 else if ( type == "AlgTool") {
00578 prop = makeInstance<IAlgTool>(*it,args);
00579 }
00580 else if ( type == "Auditor") {
00581 prop = makeInstance<IAuditor>(*it,args);
00582 }
00583 else if ( type == "ApplicationMgr") {
00584
00585 svcLoc->queryInterface(IProperty::interfaceID(), (void**)(&prop));
00586 }
00587 else {
00588 prop = makeInstance<IInterface>(*it,args);
00589 }
00590 }
00591 catch ( exception& e ) {
00592 cout << "ERROR: Error instantiating " << name
00593 << " from " << *iLib << endl;
00594 cout << "ERROR: Got exception: " << e.what() << endl;
00595 allGood = false;
00596 continue;
00597 }
00598 catch ( ... ) {
00599 cout << "ERROR: Error instantiating " << name
00600 << " from " << *iLib << endl;
00601 allGood = false;
00602 continue;
00603 }
00604 if( prop ) {
00605 genComponent( *iLib, name, type, prop->getProperties() );
00606 prop->release();
00607 } else {
00608 cout << "ERROR: could not cast IInterface* object to an IProperty* !\n"
00609 << "ERROR: return type from PluginSvc is [" << rtype << "]...\n"
00610 << "ERROR: NO Configurable will be generated for ["
00611 << name << "] !"
00612 << endl;
00613 allGood = false;
00614 }
00615 }
00616
00620 const std::string pyName = ( fs::path(m_outputDirName) /
00621 fs::path(*iLib+"Conf.py") ).string();
00622 const std::string dbName = ( fs::path(m_outputDirName) /
00623 fs::path(*iLib+"_confDb.py") ).string();
00624
00625 std::fstream py( pyName.c_str(),
00626 std::ios_base::out|std::ios_base::trunc );
00627 std::fstream db( dbName.c_str(),
00628 std::ios_base::out|std::ios_base::trunc );
00629
00630 genHeader ( py, db );
00631 genBody ( py, db );
00632 genTrailer( py, db );
00633
00634 }
00635
00636 dummySvc->release();
00637 dummySvc = 0;
00638
00639 return allGood ? EXIT_SUCCESS : EXIT_FAILURE;
00640 }
00641
00642 void configGenerator::genImport( std::ostream& s,
00643 const boost::format& frmt,
00644 std::string indent = ""){
00645
00646 std::string::size_type pos = 0, nxtpos = 0;
00647 std::string mod;
00648
00649 while ( std::string::npos != pos ){
00650
00651 nxtpos = m_configurable["Module"].find_first_of(',',pos);
00652
00653
00654 mod = m_configurable["Module"].substr(pos,nxtpos-pos);
00655 std::ostringstream import;
00656 import << boost::format(frmt) % mod;
00657
00658
00659
00660 if ( std::string::npos == nxtpos ) {
00661
00662 s << indent << import.str() << "\n" << flush;
00663 pos = std::string::npos;
00664 } else {
00665
00666 s << indent << "try:\n"
00667 << indent << py_tab << import.str() << "\n"
00668 << indent << "except ImportError:\n"
00669 << flush;
00670 pos = nxtpos+1;
00671 }
00672
00673 indent += py_tab;
00674 }
00675 }
00676
00677
00678 void configGenerator::genHeader( std::ostream& py,
00679 std::ostream& db )
00680
00681 {
00682
00683 time_t rawtime;
00684 time( &rawtime );
00685 py << "#" << ctime(&rawtime)
00686 << "\"\"\"Automatically generated. DO NOT EDIT please\"\"\"\n";
00687 if ( m_importGaudiHandles ) {
00688 py << "from GaudiKernel.GaudiHandles import *\n";
00689 }
00690
00691 genImport(py,boost::format("from %1%.Configurable import *"));
00692
00693
00694 db << "## -*- python -*- \n"
00695 << "# db file automatically generated by genconf on: "
00696 << ctime(&rawtime);
00697 db << "## insulates outside world against anything bad that could happen\n"
00698 << "## also prevents global scope pollution\n"
00699 << "def _fillCfgDb():\n";
00700 genImport(db,boost::format("from %1%.ConfigurableDb import CfgDb"),py_tab);
00701
00702 db << "\n"
00703 << py_tab << "# get a handle on the repository of Configurables\n"
00704 << py_tab << "cfgDb = CfgDb()\n"
00705 << "\n"
00706 << py_tab << "# populate the repository with informations on Configurables \n"
00707 << "\n"
00708 << flush;
00709 }
00710
00711 void configGenerator::genTrailer( std::ostream& ,
00712 std::ostream& db )
00713
00714 {
00715
00716 db << py_tab << "return #_fillCfgDb\n"
00717 << "# fill cfgDb at module import...\n"
00718 << "try:\n"
00719 << py_tab << "_fillCfgDb()\n"
00720 << py_tab << "#house cleaning...\n"
00721 << py_tab << "del _fillCfgDb\n"
00722 << "except Exception,err:\n"
00723 << py_tab << "print \"Py:ConfigurableDb ERROR Problem with [%s] content!"
00724 << "\" % __name__\n"
00725 << py_tab << "print \"Py:ConfigurableDb ERROR\",err\n"
00726 << py_tab << "print \"Py:ConfigurableDb ERROR ==> culprit is package ["
00727 << m_pkgName << "] !\"\n"
00728 << std::flush;
00729 }
00730
00731
00732 void configGenerator::genComponent( const std::string& libName,
00733 const std::string& componentName,
00734 const std::string& componentType,
00735 const vector<Property*>& properties )
00736
00737 {
00738 string cname = componentName;
00739 pythonizeName(cname);
00740
00741 typedef GaudiUtils::HashMap<std::string, std::string> PropertyDoc_t;
00742 PropertyDoc_t propDoc;
00743
00744 m_pyBuf << "\n";
00745 m_pyBuf << "class " << cname
00746 << "( " << m_configurable[componentType] << " ) :"
00747 << "\n";
00748 m_pyBuf << " __slots__ = { \n";
00749 for ( vector<Property*>::const_iterator it = properties.begin() ;
00750 it != properties.end(); ++it ) {
00751 const string pname = (*it)->name();
00752 string pvalue, ptype;
00753 pythonizeValue( (*it), pvalue, ptype );
00754 m_pyBuf << " '" << pname << "' : " << pvalue <<", # " << ptype << "\n";
00755
00756 if ( (*it)->documentation() != "none" ) {
00757 propDoc[pname] = (*it)->documentation();
00758 }
00759
00760 }
00761 m_pyBuf << " }\n";
00762 m_pyBuf << " _propertyDocDct = { \n";
00763 for ( PropertyDoc_t::const_iterator iProp = propDoc.begin();
00764 iProp != propDoc.end();
00765 ++iProp ) {
00766 m_pyBuf << std::setw(5)
00767 << "'" << iProp->first << "' : "
00768 << "\"\"\" " << iProp->second << " \"\"\",\n";
00769 }
00770 m_pyBuf << " }\n";
00771
00772 m_pyBuf
00773 << " def __init__(self, name = " << m_configurable["DefaultName"]
00774 << ", **kwargs):\n"
00775 << " super(" << cname << ", self).__init__(name)\n"
00776 << " for n,v in kwargs.items():\n"
00777 << " setattr(self, n, v)\n"
00778 << " def getDlls( self ):\n"
00779 << " return '" << libName << "'\n"
00780 << " def getType( self ):\n"
00781 << " return '" << componentName << "'\n"
00782 << " pass # class " << cname << "\n"
00783 << flush;
00784
00785
00786 const string pyName = ( fs::path(m_outputDirName) /
00787 fs::path(libName+"Conf.py") ).string();
00788 const string modName = fs::basename( fs::path( pyName ).leaf() );
00789
00790
00791 m_dbBuf
00792 << py_tab << "cfgDb.add( configurable = '" << cname << "',\n"
00793 << py_tab << " package = '" << m_pkgName << "',\n"
00794 << py_tab << " module = '" << m_pkgName << "." << modName << "',\n"
00795 << py_tab << " lib = '" << libName << "' )\n"
00796 << flush;
00797
00798 }
00799
00800 void configGenerator::pythonizeName( string& name )
00801
00802 {
00803 static string in("<>&*,: ().");
00804 static string out("__rp__s___");
00805 for ( string::iterator i = name.begin(); i != name.end(); ++i ) {
00806 if ( in.find(*i) != string::npos ) *i = out[in.find(*i)];
00807 }
00808 }
00809
00810
00811 void configGenerator::pythonizeValue( const Property* p,
00812 string& pvalue, string& ptype )
00813
00814 {
00815 const std::string cvalue = p->toString();
00816 const type_info& ti = *p->type_info();
00817 if ( ti == typeid(bool) ) {
00818 pvalue = ( cvalue == "0" || cvalue == "False" || cvalue == "false" )
00819 ? "False"
00820 : "True";
00821 ptype = "bool";
00822 }
00823 else if ( ti == typeid(char) || ti == typeid(signed char)
00824 || ti == typeid(unsigned char) ||
00825 ti == typeid(short) || ti == typeid(unsigned short) ||
00826 ti == typeid(int) || ti == typeid(unsigned int) ||
00827 ti == typeid(long) || ti == typeid(unsigned long) ) {
00828 pvalue = cvalue;
00829 ptype = "int";
00830 }
00831 else if ( ti == typeid(long long) || ti == typeid(unsigned long long) ) {
00832 pvalue = cvalue + "L";
00833 ptype = "long";
00834 }
00835 else if ( ti == typeid(float) || ti == typeid(double) ) {
00836
00837 pvalue = boost::to_lower_copy(cvalue);
00838 if ( pvalue == "nan" ) {
00839 pvalue = "float('nan')";
00840 std::cout << "WARNING: default value for ["
00841 << p->name() << "] is NaN !!"
00842 << std::endl;
00843 } else if ( std::string::npos == pvalue.find(".") &&
00844 std::string::npos == pvalue.find("e") ) {
00845 pvalue = cvalue + ".0";
00846 }
00847 ptype = "float";
00848 }
00849 else if ( ti == typeid(string) ) {
00850
00851 pvalue = "'"+cvalue+"'";
00852 ptype = "str";
00853 }
00854 else if ( ti == typeid(GaudiHandleBase) ) {
00855 m_importGaudiHandles = true;
00856 const GaudiHandleProperty& hdl
00857 = dynamic_cast<const GaudiHandleProperty&>(*p);
00858 const GaudiHandleBase& base = hdl.value();
00859
00860 pvalue = base.pythonRepr();
00861 ptype = "GaudiHandle";
00862 }
00863 else if ( ti == typeid(GaudiHandleArrayBase) ) {
00864 m_importGaudiHandles = true;
00865 const GaudiHandleArrayProperty& hdl
00866 = dynamic_cast<const GaudiHandleArrayProperty&>(*p);
00867 const GaudiHandleArrayBase& base = hdl.value();
00868
00869 pvalue = base.pythonRepr();
00870 ptype = "GaudiHandleArray";
00871 }
00872 else {
00873 pvalue = cvalue;
00874 ptype = "list";
00875 }
00876 }
00877
00878
00879 int createAppMgr()
00880
00881 {
00882 IInterface* iface = Gaudi::createApplicationMgr();
00883 SmartIF<IProperty> propMgr ( iface );
00884 SmartIF<IAppMgrUI> appUI ( iface );
00885
00886 if ( propMgr.isValid() && appUI.isValid() ) {
00887 propMgr->setProperty( "JobOptionsType", "NONE" );
00888 propMgr->setProperty( "AppName", "");
00889 propMgr->setProperty( "OutputLevel", "7");
00890 appUI->configure();
00891 return EXIT_SUCCESS;
00892 }
00893 else {
00894 return EXIT_FAILURE;
00895 }
00896 }