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