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