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