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