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 "Reflex/PluginService.h"
00049 #include "Reflex/Reflex.h"
00050 #include "Reflex/SharedLibrary.h"
00051
00052 #include "RVersion.h"
00053
00054 #include <algorithm>
00055 #include <iostream>
00056 #include <fstream>
00057 #include <sstream>
00058 #include <exception>
00059 #include <ctime>
00060 #include <set>
00061 #include <vector>
00062
00063
00064 #include "DsoUtils.h"
00065
00066
00067
00068 namespace po = boost::program_options;
00069 namespace fs = boost::filesystem;
00070
00071 using namespace std;
00072 using namespace ROOT::Reflex;
00073
00074
00075 typedef std::vector<std::string> Strings_t;
00076 typedef std::vector<fs::path> LibPathNames_t;
00077
00078 namespace {
00079 const std::string py_tab = " ";
00080 }
00081
00082 class configGenerator
00083 {
00085 string m_pkgName;
00086
00089 string m_outputDirName;
00090
00092 stringstream m_pyBuf;
00093
00096 bool m_importGaudiHandles;
00097
00102 stringstream m_dbBuf;
00103
00109 GaudiUtils::HashMap<std::string, std::string> m_configurable;
00110
00111 public:
00112 configGenerator( const string& pkgName,
00113 const string& outputDirName ) :
00114 m_pkgName ( pkgName ),
00115 m_outputDirName ( outputDirName ),
00116 m_pyBuf ( ),
00117 m_importGaudiHandles( false ),
00118 m_dbBuf ( ),
00119 m_configurable ( )
00120 {}
00121
00126 int genConfig( const Strings_t& modules );
00127
00129 void setConfigurableModule( const std::string& moduleName )
00130 {
00131 m_configurable[ "Module" ] = moduleName;
00132 }
00133
00135 void setConfigurableDefaultName( const std::string& defaultName )
00136 {
00137 m_configurable[ "DefaultName" ] = defaultName;
00138 }
00139
00141 void setConfigurableAlgorithm( const std::string& cfgAlgorithm )
00142 {
00143 m_configurable[ "Algorithm" ] = cfgAlgorithm;
00144 }
00145
00147 void setConfigurableAlgTool( const std::string& cfgAlgTool )
00148 {
00149 m_configurable[ "AlgTool" ] = cfgAlgTool;
00150 }
00151
00153 void setConfigurableAuditor( const std::string& cfgAuditor )
00154 {
00155 m_configurable[ "Auditor" ] = cfgAuditor;
00156 }
00157
00159 void setConfigurableService( const std::string& cfgService )
00160 {
00161 m_configurable[ "Service" ] = cfgService;
00162 m_configurable[ "ApplicationMgr" ] = cfgService;
00163 }
00164
00165 private:
00166 void genComponent( const std::string& libName,
00167 const std::string& componentName,
00168 const std::string& componentType,
00169 const vector<Property*>& properties );
00170 void genImport( std::ostream& s, const boost::format& frmt,std::string indent);
00171 void genHeader( std::ostream& pyOut, std::ostream& dbOut );
00172 void genBody( std::ostream& pyOut,
00173 std::ostream& dbOut ) {
00174 pyOut << m_pyBuf.str() << flush;
00175 dbOut << m_dbBuf.str() << flush;
00176 }
00177 void genTrailer( std::ostream& pyOut,
00178 std::ostream& dbOut );
00179
00181 void pythonizeValue( const Property* prop,
00182 string& pvalue,
00183 string& ptype );
00184
00186 void pythonizeName( string& name );
00187 };
00188
00189 int createAppMgr();
00190
00191
00192 int main ( int argc, char** argv )
00193
00194 {
00195 fs::path::default_name_check(fs::native);
00196 fs::path pwd = fs::initial_path();
00197 fs::path out;
00198 Strings_t libs;
00199 std::string pkgName;
00200
00201
00202 po::options_description generic("Generic options");
00203 generic.add_options()
00204 ("help,h",
00205 "produce this help message")
00206 ("package-name,p",
00207 po::value<string>(),
00208 "name of the package for which we create the configurables file")
00209 ("input-libraries,i",
00210 po::value<string>(),
00211 "libraries to extract the component configurables from")
00212 ("input-cfg,c",
00213 po::value<string>(),
00214 "path to the cfg file holding the description of the Configurable base "
00215 "classes, the python module holding the Configurable definitions, etc...")
00216 ("output-dir,o",
00217 po::value<string>()->default_value("../genConf"),
00218 "output directory for genconf files.")
00219 ("debug-level,d",
00220 po::value<int>()->default_value(0),
00221 "debug level")
00222 ("load-library,l",
00223 po::value< Strings_t >()->composing(),
00224 "preloading library")
00225 ;
00226
00227
00228
00229 po::options_description config("Configuration");
00230 config.add_options()
00231 ("configurable-module",
00232 po::value<string>()->default_value("AthenaCommon"),
00233 "Name of the module holding the configurable classes")
00234 ("configurable-default-name",
00235 po::value<string>()->default_value("Configurable.DefaultName"),
00236 "Default name for the configurable instance")
00237 ("configurable-algorithm",
00238 po::value<string>()->default_value("ConfigurableAlgorithm"),
00239 "Name of the configurable base class for Algorithm components")
00240 ("configurable-algtool",
00241 po::value<string>()->default_value("ConfigurableAlgTool"),
00242 "Name of the configurable base class for AlgTool components")
00243 ("configurable-auditor",
00244 po::value<string>()->default_value("ConfigurableAuditor"),
00245 "Name of the configurable base class for Auditor components")
00246 ("configurable-service",
00247 po::value<string>()->default_value("ConfigurableService"),
00248 "Name of the configurable base class for Service components")
00249 ;
00250
00251 po::options_description cmdline_options;
00252 cmdline_options.add(generic).add(config);
00253
00254 po::options_description config_file_options;
00255 config_file_options.add(config);
00256
00257 po::options_description visible("Allowed options");
00258 visible.add(generic).add(config);
00259
00260 po::variables_map vm;
00261
00262 try {
00263 po::store( po::command_line_parser(argc, argv).
00264 options(cmdline_options).run(),
00265 vm );
00266
00267 po::notify(vm);
00268
00269
00270 if( vm.count("input-cfg") ) {
00271 string cfgFileName = vm["input-cfg"].as<string>();
00272 cfgFileName = fs::complete( fs::path( cfgFileName,
00273 fs::native ) ).string();
00274 std::ifstream ifs( cfgFileName.c_str() );
00275 po::store( parse_config_file( ifs, config_file_options ), vm );
00276 }
00277
00278 po::notify(vm);
00279 }
00280 catch ( po::error& err ) {
00281 cout << "ERR0R: error detected while parsing command options: "<< err.what() << endl;
00282 return EXIT_FAILURE;
00283 }
00284
00285
00286 if( vm.count("help")) {
00287 cout << visible << endl;
00288 return EXIT_FAILURE;
00289 }
00290
00291 if( vm.count("package-name") ) {
00292 pkgName = vm["package-name"].as<string>();
00293 }
00294 else {
00295 cout << "ERROR: 'package-name' required" << endl;
00296 cout << visible << endl;
00297 return EXIT_FAILURE;
00298 }
00299
00300 if( vm.count("input-libraries") ) {
00301
00302
00303
00304 Strings_t inputLibs;
00305 {
00306 string tmp = vm["input-libraries"].as<string>();
00307 boost::trim(tmp);
00308 boost::split( inputLibs, tmp,
00309 boost::is_any_of(" "),
00310 boost::token_compress_on );
00311 }
00312
00313
00314 libs.reserve( inputLibs.size() );
00315 for ( Strings_t::const_iterator iLib = inputLibs.begin();
00316 iLib != inputLibs.end();
00317 ++iLib ) {
00318 fs::path libPath = fs::path( *iLib, fs::native );
00319 std::string lib = libPath.leaf().substr(0, libPath.leaf().find('.') );
00320 if ( 0 == lib.find("lib") ) {
00321 lib = lib.substr(3);
00322 }
00323
00324 if ( !lib.empty() &&
00325 std::find( libs.begin(), libs.end(), lib ) == libs.end() ) {
00326 libs.push_back( lib );
00327 }
00328 }
00329 if ( libs.empty() ) {
00330 cout << "ERROR: input component library(ies) required !\n"
00331 << "ERROR: 'input-libraries' argument was ["
00332 << vm["input-libraries"].as<string>()
00333 << "]"
00334 << endl;
00335 return EXIT_FAILURE;
00336 }
00337 }
00338 else {
00339 cout << "ERROR: input component library(ies) required" << endl;
00340 cout << visible << endl;
00341 return EXIT_FAILURE;
00342 }
00343
00344 if( vm.count("output-dir") ) {
00345 out = fs::complete( fs::path( vm["output-dir"].as<string>(),
00346 fs::native ) );
00347 }
00348
00349 if ( vm.count("debug-level") ) {
00350 PluginService::SetDebug( vm["debug-level"].as<int>() );
00351 }
00352
00353 if ( vm.count("load-library") ) {
00354 Strings_t lLib_list = vm["load-library"].as< Strings_t >();
00355 for (Strings_t::const_iterator lLib=lLib_list.begin();
00356 lLib != lLib_list.end();
00357 ++lLib) {
00358
00359 SharedLibrary tmplib(*lLib) ;
00360 tmplib.Load() ;
00361 }
00362 }
00363
00364
00365 if ( !fs::exists( out ) ) {
00366 try {
00367 fs::create_directory(out);
00368 }
00369 catch ( fs::filesystem_error err ) {
00370 cout << "ERR0R: error creating directory: "<< err.what() << endl;
00371 return EXIT_FAILURE;
00372 }
00373 }
00374
00375 cout << ":::::: libraries : [ ";
00376 copy( libs.begin(), libs.end(), ostream_iterator<string>(cout, " ") );
00377 cout << "] ::::::" << endl;
00378
00379 configGenerator py( pkgName, out.string() );
00380 py.setConfigurableModule (vm["configurable-module"].as<string>());
00381 py.setConfigurableDefaultName(vm["configurable-default-name"].as<string>());
00382 py.setConfigurableAlgorithm (vm["configurable-algorithm"].as<string>());
00383 py.setConfigurableAlgTool (vm["configurable-algtool"].as<string>());
00384 py.setConfigurableAuditor (vm["configurable-auditor"].as<string>());
00385 py.setConfigurableService (vm["configurable-service"].as<string>());
00386
00387 int sc = EXIT_FAILURE;
00388 try {
00389 sc = py.genConfig( libs );
00390 }
00391 catch ( exception& e ) {
00392 cout << "ERROR: Could not generate Configurable(s) !\n"
00393 << "ERROR: Got exception: " << e.what() << endl;
00394 return EXIT_FAILURE;
00395 }
00396
00397 if ( EXIT_SUCCESS == sc ) {
00398
00399 fstream initPy( ( out / fs::path( "__init__.py" ) ).string().c_str(),
00400 std::ios_base::out|std::ios_base::trunc );
00401 initPy << "## Hook for " << pkgName << " genConf module\n" << flush;
00402 }
00403
00404 cout << ":::::: libraries : [ ";
00405 copy( libs.begin(), libs.end(), ostream_iterator<string>(cout, " ") );
00406 cout << "] :::::: [DONE]" << endl;
00407
00408 return sc;
00409 }
00410
00413 inline std::string getId(const Member & m) {
00414 return (m.Properties().HasProperty("id") && (m.Properties().PropertyValue("id").TypeInfo() == typeid(std::string))) ?
00415 m.Properties().PropertyAsString("id") :
00416 m.Properties().PropertyAsString("name") ;
00417 }
00418
00419 template <class T>
00420 IProperty *makeInstance(const Member &member, const vector<void*> &args)
00421 {
00422 Object dummy;
00423 T* obj;
00424 #if ROOT_VERSION_CODE < ROOT_VERSION(5,21,6)
00425 obj = static_cast<T*>(member.Invoke(dummy,args).Address());
00426 #else
00427 member.Invoke(dummy,obj,args);
00428 #endif
00429 return dynamic_cast<IProperty*>(obj);
00430 }
00431
00432
00433
00434 int configGenerator::genConfig( const Strings_t& libs )
00435
00436 {
00437
00438 StatusCode::disableChecking();
00439
00440 const Strings_t::const_iterator endLib = libs.end();
00441
00442 const std::string gaudiSvc = "GaudiSvc";
00443 const bool isGaudiSvc = ( std::find( libs.begin(), endLib, gaudiSvc ) != endLib );
00444
00445
00446 if ( !isGaudiSvc && createAppMgr() ) {
00447 cout << "ERROR: ApplicationMgr can not be created. Check environment" << endl;
00448 return EXIT_FAILURE;
00449 }
00450
00451
00452 Scope factories = Scope::ByName(PLUGINSVC_FACTORY_NS);
00453 if ( !factories ) {
00454 cout << "ERROR: No PluginSvc factory namespace could be found" << endl;
00455 return EXIT_FAILURE;
00456 }
00457
00458 ISvcLocator* svcLoc = Gaudi::svcLocator();
00459 IInterface* dummySvc = new Service( "DummySvc", svcLoc );
00460 dummySvc->addRef();
00461
00462 bool allGood = true;
00463
00464
00465 for ( Strings_t::const_iterator iLib=libs.begin(); iLib != endLib; ++iLib ) {
00466
00467 std::cout << ":::: processing library: " << *iLib << "..." << std::endl;
00468
00469
00470 m_importGaudiHandles = false;
00471 m_pyBuf.str("");
00472 m_dbBuf.str("");
00473
00474
00475
00476 set<string> bkgNames;
00477 if ( !isGaudiSvc ) {
00478 for ( Member_Iterator it = factories.FunctionMember_Begin();
00479 it != factories.FunctionMember_End(); ++it ) {
00480 string ident = getId(*it);
00481 if ( PluginService::Debug() > 0 ) {
00482 cout << "::: " << ident << endl;
00483 }
00484 bkgNames.insert( ident );
00485 }
00486 }
00487 const set<string>::const_iterator bkgNamesEnd = bkgNames.end();
00488
00489
00490 System::ImageHandle handle;
00491 unsigned long err = System::loadDynamicLib( *iLib, &handle );
00492 if ( err != 1 ) {
00493 cout << "ERROR: " << System::getLastErrorString() << endl;
00494 allGood = false;
00495 continue;
00496 }
00497
00498 for ( Member_Iterator it = factories.FunctionMember_Begin();
00499 it != factories.FunctionMember_End();
00500 ++it ) {
00501 const string ident = getId(*it);
00502 if ( bkgNames.find(ident) != bkgNamesEnd ) {
00503 if ( PluginService::Debug() > 0 ) {
00504 cout << "\t==> skipping [" << ident << "]..." << endl;
00505 }
00506 continue;
00507 }
00508
00509
00510
00511
00512
00513
00514 if ( !DsoUtils::inDso( *it, DsoUtils::libNativeName(*iLib) ) ) {
00515 cout << "WARNING: library [" << *iLib << "] requested factory "
00516 << "from another library ["
00517 << DsoUtils::dsoName(*it) << "]"
00518 << " ==> [" << ident << "] !!"
00519 << endl;
00520 continue;
00521 }
00522
00523 const string rtype = it->TypeOf().ReturnType().Name();
00524 string type;
00525 bool known = true;
00526 if ( ident == "ApplicationMgr" ) type = "ApplicationMgr";
00527 else if ( rtype == "IInterface*" ) type = "IInterface";
00528 else if ( rtype == "IAlgorithm*" ) type = "Algorithm";
00529 else if ( rtype == "IService*" ) type = "Service";
00530 else if ( rtype == "IAlgTool*" ) type = "AlgTool";
00531 else if ( rtype == "IAuditor*" ) type = "Auditor";
00532 else if ( rtype == "IConverter*" ) type = "Converter";
00533 else if ( rtype == "DataObject*" ) type = "DataObject";
00534 else type = "Unknown", known = false;
00535 string name = ident;
00536
00537 boost::trim(name);
00538
00539 cout << " - component: " << name << endl;
00540
00541 if ( type == "IInterface" ) {
00544 continue;
00545 }
00546
00547 if ( type == "Converter" || type == "DataObject" ) {
00549 continue;
00550 }
00551
00552
00555
00556
00557 if ( !known ) {
00558 cout << "WARNING: Unknown (return) type [" << rtype << "] !!\n"
00559 << "WARNING: component [" << ident << "] is skipped !"
00560 << endl;
00561 allGood = false;
00562 continue;
00563 }
00564
00565 string cname = "DefaultName";
00566 vector<void*> args;
00567 args.reserve( 3 );
00568 if ( type == "AlgTool" ) {
00569 args.resize( 3 );
00570 args[0] = &cname;
00571 args[1] = &type;
00572 args[2] = dummySvc;
00573 }
00574 else {
00575 args.resize( 2 );
00576 args[0] = &cname;
00577 args[1] = svcLoc;
00578 }
00579 IProperty* prop = 0;
00580 try {
00581 if ( type == "Algorithm" ) {
00582 prop = makeInstance<IAlgorithm>(*it,args);
00583 }
00584 else if ( type == "Service") {
00585 prop = makeInstance<IService>(*it,args);
00586 }
00587 else if ( type == "AlgTool") {
00588 prop = makeInstance<IAlgTool>(*it,args);
00589 }
00590 else if ( type == "Auditor") {
00591 prop = makeInstance<IAuditor>(*it,args);
00592 }
00593 else if ( type == "ApplicationMgr") {
00594
00595 svcLoc->queryInterface(IProperty::interfaceID(), (void**)(&prop));
00596 }
00597 else {
00598 prop = makeInstance<IInterface>(*it,args);
00599 }
00600 }
00601 catch ( exception& e ) {
00602 cout << "ERROR: Error instantiating " << name
00603 << " from " << *iLib << endl;
00604 cout << "ERROR: Got exception: " << e.what() << endl;
00605 allGood = false;
00606 continue;
00607 }
00608 catch ( ... ) {
00609 cout << "ERROR: Error instantiating " << name
00610 << " from " << *iLib << endl;
00611 allGood = false;
00612 continue;
00613 }
00614 if( prop ) {
00615 genComponent( *iLib, name, type, prop->getProperties() );
00616 prop->release();
00617 } else {
00618 cout << "ERROR: could not cast IInterface* object to an IProperty* !\n"
00619 << "ERROR: return type from PluginSvc is [" << rtype << "]...\n"
00620 << "ERROR: NO Configurable will be generated for ["
00621 << name << "] !"
00622 << endl;
00623 allGood = false;
00624 }
00625 }
00626
00630 const std::string pyName = ( fs::path(m_outputDirName) /
00631 fs::path(*iLib+"Conf.py") ).string();
00632 const std::string dbName = ( fs::path(m_outputDirName) /
00633 fs::path(*iLib+"_confDb.py") ).string();
00634
00635 std::fstream py( pyName.c_str(),
00636 std::ios_base::out|std::ios_base::trunc );
00637 std::fstream db( dbName.c_str(),
00638 std::ios_base::out|std::ios_base::trunc );
00639
00640 genHeader ( py, db );
00641 genBody ( py, db );
00642 genTrailer( py, db );
00643
00644 }
00645
00646 dummySvc->release();
00647 dummySvc = 0;
00648
00649 return allGood ? EXIT_SUCCESS : EXIT_FAILURE;
00650 }
00651
00652 void configGenerator::genImport( std::ostream& s,
00653 const boost::format& frmt,
00654 std::string indent = ""){
00655
00656 std::string::size_type pos = 0, nxtpos = 0;
00657 std::string mod;
00658
00659 while ( std::string::npos != pos ){
00660
00661 nxtpos = m_configurable["Module"].find_first_of(',',pos);
00662
00663
00664 mod = m_configurable["Module"].substr(pos,nxtpos-pos);
00665 std::ostringstream import;
00666 import << boost::format(frmt) % mod;
00667
00668
00669
00670 if ( std::string::npos == nxtpos ) {
00671
00672 s << indent << import.str() << "\n" << flush;
00673 pos = std::string::npos;
00674 } else {
00675
00676 s << indent << "try:\n"
00677 << indent << py_tab << import.str() << "\n"
00678 << indent << "except ImportError:\n"
00679 << flush;
00680 pos = nxtpos+1;
00681 }
00682
00683 indent += py_tab;
00684 }
00685 }
00686
00687
00688 void configGenerator::genHeader( std::ostream& py,
00689 std::ostream& db )
00690
00691 {
00692
00693 time_t rawtime;
00694 time( &rawtime );
00695 py << "#" << ctime(&rawtime)
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 << ctime(&rawtime);
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 }