4 #pragma warning ( disable : 4273 )
14 #pragma warning(disable:279)
16 #if !defined(_WIN32) && !defined(_MSC_VER)
21 #include "boost/program_options.hpp"
23 #if defined(__ICC) && !defined(_WIN32) && (_MSC_VER == 0)
28 #include "boost/filesystem/operations.hpp"
29 #include "boost/filesystem/exception.hpp"
30 #include "boost/filesystem/convenience.hpp"
31 #include "boost/algorithm/string/split.hpp"
32 #include "boost/algorithm/string/classification.hpp"
33 #include "boost/algorithm/string/trim.hpp"
34 #include "boost/algorithm/string/case_conv.hpp"
35 #include "boost/algorithm/string/replace.hpp"
36 #include "boost/format.hpp"
37 #include "boost/regex.hpp"
39 #include <boost/log/core.hpp>
40 #include <boost/log/trivial.hpp>
41 #include <boost/log/expressions.hpp>
42 #include <boost/log/utility/setup/console.hpp>
43 #include <boost/log/utility/setup/common_attributes.hpp>
45 #include "GaudiKernel/System.h"
46 #include "GaudiKernel/ISvcLocator.h"
47 #include "GaudiKernel/IProperty.h"
48 #include "GaudiKernel/IAppMgrUI.h"
49 #include "GaudiKernel/IAlgorithm.h"
50 #include "GaudiKernel/IAlgTool.h"
51 #include "GaudiKernel/IAuditor.h"
52 #include "GaudiKernel/IAppMgrUI.h"
53 #include "GaudiKernel/Service.h"
54 #include "GaudiKernel/Bootstrap.h"
55 #include "GaudiKernel/SmartIF.h"
56 #include "GaudiKernel/HashMap.h"
57 #include "GaudiKernel/GaudiHandle.h"
59 #include "GaudiKernel/Auditor.h"
60 #include "GaudiKernel/Service.h"
61 #include "GaudiKernel/AlgTool.h"
62 #include "GaudiKernel/Algorithm.h"
64 #include "GaudiKernel/Time.h"
66 #include <Gaudi/PluginService.h>
78 namespace po = boost::program_options;
79 namespace fs = boost::filesystem;
81 #define LOG_ERROR BOOST_LOG_TRIVIAL(error)
82 #define LOG_WARNING BOOST_LOG_TRIVIAL(warning)
83 #define LOG_INFO BOOST_LOG_TRIVIAL(info)
84 #define LOG_DEBUG BOOST_LOG_TRIVIAL(debug)
91 typedef std::vector<std::string>
Strings_t;
95 const std::string py_tab =
" ";
99 const boost::regex pythonIdentifier(
"^[a-zA-Z_][a-zA-Z0-9_]*$");
133 const string& outputDirName ) :
134 m_pkgName ( pkgName ),
135 m_outputDirName ( outputDirName ),
137 m_importGaudiHandles(
false ),
157 m_configurable[
"DefaultName" ] = defaultName;
163 m_configurable[
"Algorithm" ] = cfgAlgorithm;
169 m_configurable[
"AlgTool" ] = cfgAlgTool;
175 m_configurable[
"Auditor" ] = cfgAuditor;
181 m_configurable[
"Service" ] = cfgService;
182 m_configurable[
"ApplicationMgr" ] = cfgService;
186 int genComponent(
const std::string& libName,
187 const std::string& componentName,
188 const std::string& componentType,
189 const vector<Property*>& properties );
191 void genHeader( std::ostream& pyOut, std::ostream& dbOut );
193 std::ostream& dbOut ) {
194 pyOut << m_pyBuf.str() << flush;
195 dbOut << m_dbBuf.str() << flush;
197 void genTrailer( std::ostream& pyOut,
198 std::ostream& dbOut );
201 void pythonizeValue(
const Property* prop,
206 void pythonizeName(
string& name );
214 namespace keywords = boost::log::keywords;
215 namespace expr = boost::log::expressions;
217 logging::add_console_log
222 <<
"[" << std::setw(7) << std::left
223 << logging::trivial::severity
224 <<
"] " << expr::smessage
230 logging::trivial::severity >= level
241 ? boost::log::trivial::info
242 : boost::log::trivial::warning);
248 std::string userModule;
251 po::options_description
generic(
"Generic options");
252 generic.add_options()
254 "produce this help message")
257 "name of the package for which we create the configurables file")
258 (
"input-libraries,i",
260 "libraries to extract the component configurables from")
263 "path to the cfg file holding the description of the Configurable base "
264 "classes, the python module holding the Configurable definitions, etc...")
266 po::value<string>()->default_value(
"../genConf"),
267 "output directory for genconf files.")
269 po::value<int>()->default_value(0),
272 po::value< Strings_t >()->composing(),
273 "preloading library")
276 "user-defined module to be imported by the genConf-generated one")
278 "do not generate the (empty) __init__.py")
283 po::options_description config(
"Configuration");
285 (
"configurable-module",
286 po::value<string>()->default_value(
"AthenaCommon"),
287 "Name of the module holding the configurable classes")
288 (
"configurable-default-name",
289 po::value<string>()->default_value(
"Configurable.DefaultName"),
290 "Default name for the configurable instance")
291 (
"configurable-algorithm",
292 po::value<string>()->default_value(
"ConfigurableAlgorithm"),
293 "Name of the configurable base class for Algorithm components")
294 (
"configurable-algtool",
295 po::value<string>()->default_value(
"ConfigurableAlgTool"),
296 "Name of the configurable base class for AlgTool components")
297 (
"configurable-auditor",
298 po::value<string>()->default_value(
"ConfigurableAuditor"),
299 "Name of the configurable base class for Auditor components")
300 (
"configurable-service",
301 po::value<string>()->default_value(
"ConfigurableService"),
302 "Name of the configurable base class for Service components")
305 po::options_description cmdline_options;
306 cmdline_options.add(
generic).add(config);
308 po::options_description config_file_options;
309 config_file_options.add(config);
311 po::options_description visible(
"Allowed options");
312 visible.add(
generic).add(config);
314 po::variables_map vm;
317 po::store( po::command_line_parser(argc, argv).
318 options(cmdline_options).run(),
324 if( vm.count(
"input-cfg") ) {
325 string cfgFileName = vm[
"input-cfg"].as<
string>();
326 cfgFileName = fs::system_complete(
fs::path( cfgFileName ) ).string();
327 std::ifstream ifs( cfgFileName.c_str() );
328 po::store( parse_config_file( ifs, config_file_options ), vm );
333 catch ( po::error& err ) {
335 <<
"error detected while parsing command options: "
341 if( vm.count(
"help")) {
342 cout << visible << endl;
346 if( vm.count(
"package-name") ) {
347 pkgName = vm[
"package-name"].as<
string>();
351 cout << visible << endl;
355 if( vm.count(
"user-module") ) {
356 userModule = vm[
"user-module"].as<
string>();
357 LOG_INFO <<
"INFO: will import user module " << userModule;
360 if( vm.count(
"input-libraries") ) {
366 string tmp = vm[
"input-libraries"].as<
string>();
368 boost::split( inputLibs, tmp,
369 boost::is_any_of(
" "),
370 boost::token_compress_on );
374 libs.reserve( inputLibs.size() );
375 for ( Strings_t::const_iterator iLib = inputLibs.begin();
376 iLib != inputLibs.end();
378 std::string lib =
fs::path(*iLib).stem().string();
379 if ( 0 == lib.find(
"lib") ) {
384 std::find( libs.begin(), libs.end(), lib ) == libs.end() ) {
385 libs.push_back( lib );
388 if ( libs.empty() ) {
389 LOG_ERROR <<
"input component library(ies) required !\n";
390 LOG_ERROR <<
"'input-libraries' argument was ["
391 << vm[
"input-libraries"].as<
string>()
397 LOG_ERROR <<
"input component library(ies) required";
398 cout << visible << endl;
402 if( vm.count(
"output-dir") ) {
403 out = fs::system_complete(
fs::path( vm[
"output-dir"].as<string>() ) );
406 if ( vm.count(
"debug-level") ) {
410 if ( vm.count(
"load-library") ) {
412 for (Strings_t::const_iterator lLib=lLib_list.begin();
413 lLib != lLib_list.end();
425 if ( !fs::exists( out ) ) {
427 fs::create_directory(out);
429 catch ( fs::filesystem_error &err ) {
430 LOG_ERROR <<
"error creating directory: "<< err.what();
436 std::ostringstream
msg;
437 msg <<
":::::: libraries : [ ";
438 copy( libs.begin(), libs.end(), ostream_iterator<string>(
msg,
" ") );
445 py.setConfigurableDefaultName(vm[
"configurable-default-name"].as<string>());
446 py.setConfigurableAlgorithm (vm[
"configurable-algorithm"].as<string>());
447 py.setConfigurableAlgTool (vm[
"configurable-algtool"].as<string>());
448 py.setConfigurableAuditor (vm[
"configurable-auditor"].as<string>());
449 py.setConfigurableService (vm[
"configurable-service"].as<string>());
451 int sc = EXIT_FAILURE;
453 sc = py.genConfig( libs, userModule );
455 catch ( exception& e ) {
456 cout <<
"ERROR: Could not generate Configurable(s) !\n"
457 <<
"ERROR: Got exception: " << e.what() << endl;
461 if ( EXIT_SUCCESS == sc && ! vm.count(
"no-init")) {
463 fstream initPy( ( out /
fs::path(
"__init__.py" ) ).
string().c_str(),
464 std::ios_base::out|std::ios_base::trunc );
465 initPy <<
"## Hook for " << pkgName <<
" genConf module\n" << flush;
469 std::ostringstream
msg;
470 msg <<
":::::: libraries : [ ";
471 copy( libs.begin(), libs.end(), ostream_iterator<string>(
msg,
" ") );
472 msg <<
"] :::::: [DONE]";
485 const Strings_t::const_iterator endLib = libs.end();
487 const std::string gaudiSvc =
"GaudiCoreSvc";
488 const bool isGaudiSvc = ( std::find( libs.begin(), endLib, gaudiSvc ) != endLib );
492 cout <<
"ERROR: ApplicationMgr can not be created. Check environment" << endl;
498 Registry&
registry = Registry::instance();
500 std::set<std::string> bkgNames = registry.loadedFactories();
509 for ( Strings_t::const_iterator iLib=libs.begin(); iLib != endLib; ++iLib ) {
511 LOG_INFO <<
":::: processing library: " << *iLib <<
"...";
514 m_importGaudiHandles =
false;
527 std::set<std::string>
factories = registry.loadedFactories();
529 for ( std::set<std::string>::iterator it = factories.begin();
530 it != factories.end(); ++it ) {
531 const string ident = *it;
532 if ( bkgNames.find(ident) != bkgNames.end() ) {
534 LOG_INFO <<
"\t==> skipping [" << ident <<
"]...";
539 const Registry::FactoryInfo info = registry.getInfo(*it);
540 const string rtype = info.rtype;
543 if (info.properties.find(
"ReflexName") != info.properties.end())
551 LOG_WARNING <<
"library [" << *iLib <<
"] exposes factory ["
552 << ident <<
"] which is declared in ["
553 << DsoUtils::dsoName(info.ptr) <<
"] !!";
559 if ( ident ==
"ApplicationMgr" ) type =
"ApplicationMgr";
560 else if ( rtype ==
typeid(
IInterface*).name() ) type =
"IInterface";
561 else if ( rtype ==
typeid(
IAlgorithm*).name() ) type =
"Algorithm";
562 else if ( rtype ==
typeid(
IService* ).name() ) type =
"Service";
563 else if ( rtype ==
typeid(
IAlgTool* ).name() ) type =
"AlgTool";
564 else if ( rtype ==
typeid(
IAuditor* ).name() ) type =
"Auditor";
565 else if ( rtype ==
typeid(
IConverter*).name() ) type =
"Converter";
566 else if ( rtype ==
typeid(
DataObject*).name() ) type =
"DataObject";
567 else type =
"Unknown", known =
false;
572 if ( type ==
"IInterface" ) {
578 if ( type ==
"Converter" || type ==
"DataObject" ) {
585 <<
" Component [" << ident <<
"] is skipped !";
589 LOG_INFO <<
" - component: " << info.className
590 <<
" (" << (info.className != name ? (name +
": ")
594 string cname =
"DefaultName";
597 if ( type ==
"Algorithm" ) {
600 else if ( type ==
"Service") {
603 else if ( type ==
"AlgTool") {
604 prop =
SmartIF<IAlgTool>(AlgTool::Factory::create(ident, cname, type, dummySvc));
608 else if ( type ==
"Auditor") {
611 else if ( type ==
"ApplicationMgr") {
618 catch ( exception& e ) {
619 LOG_ERROR <<
"Error instantiating " << name
620 <<
" from " << *iLib;
621 LOG_ERROR <<
"Got exception: " << e.what();
626 LOG_ERROR <<
"Error instantiating " << name
627 <<
" from " << *iLib;
632 if (genComponent( *iLib, name, type, prop->
getProperties() )) {
637 LOG_ERROR <<
"could not cast IInterface* object to an IProperty* !";
638 LOG_ERROR <<
"return type from PluginSvc is [" << rtype <<
"]...";
639 LOG_ERROR <<
"NO Configurable will be generated for ["
648 const std::string pyName = (
fs::path(m_outputDirName) /
649 fs::path(*iLib+
"Conf.py") ).
string();
650 const std::string dbName = (
fs::path(m_outputDirName) /
651 fs::path(*iLib+
".confdb") ).
string();
653 std::fstream py( pyName.c_str(),
654 std::ios_base::out|std::ios_base::trunc );
655 std::fstream db( dbName.c_str(),
656 std::ios_base::out|std::ios_base::trunc );
658 genHeader ( py, db );
659 if (!userModule.empty())
660 py <<
"from " << userModule <<
" import *" <<endl;
662 genTrailer( py, db );
669 return allGood ? EXIT_SUCCESS : EXIT_FAILURE;
676 std::string::size_type pos = 0, nxtpos = 0;
679 while ( std::string::npos != pos ){
681 nxtpos = m_configurable[
"Module"].find_first_of(
',',pos);
684 mod = m_configurable[
"Module"].substr(pos,nxtpos-pos);
685 std::ostringstream
import;
690 if ( std::string::npos == nxtpos ) {
692 s <<
indent <<
import.str() <<
"\n" << flush;
693 pos = std::string::npos;
697 <<
indent << py_tab <<
import.str() <<
"\n"
698 <<
indent <<
"except ImportError:\n"
715 <<
"\"\"\"Automatically generated. DO NOT EDIT please\"\"\"\n";
716 if ( m_importGaudiHandles ) {
717 py <<
"from GaudiKernel.GaudiHandles import *\n";
720 genImport(py,
boost::format(
"from %1%.Configurable import *"));
723 db <<
"## -*- ascii -*- \n"
724 <<
"# db file automatically generated by genconf on: "
735 db <<
"## " << m_pkgName <<
"\n"
742 const std::string& componentName,
743 const std::string& componentType,
744 const vector<Property*>& properties )
747 string cname = componentName;
748 pythonizeName(cname);
751 PropertyDoc_t propDoc;
754 m_pyBuf <<
"class " << cname
755 <<
"( " << m_configurable[componentType] <<
" ) :"
757 m_pyBuf <<
" __slots__ = { \n";
758 for ( vector<Property*>::const_iterator it = properties.begin() ;
759 it != properties.end(); ++it ) {
761 const string pname = (*it)->name();
763 if (!boost::regex_match(pname, pythonIdentifier)) {
764 std::cout <<
"ERROR: invalid property name \"" << pname
765 <<
"\" in component " << cname
766 <<
" (invalid Python identifier)" << std::endl;
768 m_pyBuf <<
" #ERROR-invalid identifier '" << pname <<
"'\n"
773 string pvalue, ptype;
774 pythonizeValue( (*it), pvalue, ptype );
775 m_pyBuf <<
" '" << pname <<
"' : " << pvalue <<
", # " << ptype <<
"\n";
777 if ( (*it)->documentation() !=
"none" ) {
778 propDoc[
pname] = (*it)->documentation();
783 m_pyBuf <<
" _propertyDocDct = { \n";
784 for ( PropertyDoc_t::const_iterator iProp = propDoc.begin();
785 iProp != propDoc.end();
787 m_pyBuf << std::setw(5)
788 <<
"'" << iProp->first <<
"' : "
789 <<
"\"\"\" " << iProp->second <<
" \"\"\",\n";
794 <<
" def __init__(self, name = " << m_configurable[
"DefaultName"]
796 <<
" super(" << cname <<
", self).__init__(name)\n"
797 <<
" for n,v in kwargs.items():\n"
798 <<
" setattr(self, n, v)\n"
799 <<
" def getDlls( self ):\n"
800 <<
" return '" << libName <<
"'\n"
801 <<
" def getType( self ):\n"
802 <<
" return '" << componentName <<
"'\n"
803 <<
" pass # class " << cname <<
"\n"
807 const string pyName = (
fs::path(m_outputDirName) /
808 fs::path(libName+
"Conf.py") ).
string();
813 << m_pkgName <<
"." << modName <<
" "
814 << libName <<
" " << cname
824 static string in(
"<>&*,: ().");
825 static string out(
"__rp__s___");
826 boost::algorithm::replace_all(name,
", ",
",");
827 for ( string::iterator
i = name.begin();
i != name.end(); ++
i ) {
828 if ( in.find(*
i) != string::npos ) *
i = out[in.find(*
i)];
834 string& pvalue,
string& ptype )
837 const std::string cvalue = p->
toString();
839 if ( ti ==
typeid(
bool) ) {
840 pvalue = ( cvalue ==
"0" || cvalue ==
"False" || cvalue ==
"false" )
845 else if ( ti ==
typeid(
char) || ti ==
typeid(
signed char)
846 || ti ==
typeid(
unsigned char) ||
847 ti ==
typeid(short) || ti ==
typeid(
unsigned short) ||
848 ti ==
typeid(int) || ti ==
typeid(
unsigned int) ||
849 ti ==
typeid(long) || ti ==
typeid(
unsigned long) ) {
853 else if ( ti ==
typeid(
long long) || ti ==
typeid(
unsigned long long) ) {
854 pvalue = cvalue +
"L";
857 else if ( ti ==
typeid(
float) || ti ==
typeid(double) ) {
859 pvalue = boost::to_lower_copy(cvalue);
860 if ( pvalue ==
"nan" ) {
861 pvalue =
"float('nan')";
862 std::cout <<
"WARNING: default value for ["
863 << p->
name() <<
"] is NaN !!"
865 }
else if ( std::string::npos == pvalue.find(
".") &&
866 std::string::npos == pvalue.find(
"e") ) {
867 pvalue = cvalue +
".0";
871 else if ( ti ==
typeid(
string) ) {
873 pvalue =
"'"+cvalue+
"'";
877 m_importGaudiHandles =
true;
883 ptype =
"GaudiHandle";
886 m_importGaudiHandles =
true;
892 ptype =
"GaudiHandleArray";
895 std::ostringstream v_str;
896 v_str.setf(std::ios::fixed);
898 pvalue = v_str.str();
903 #include "GaudiKernel/IMessageSvc.h"
918 msgSvc->setProperty(
"setWarning",
"['DefaultName', 'PropertyMgr']");
919 msgSvc->setProperty(
"Format",
"%T %0W%M");
const GaudiHandleArrayBase & value() const
int genConfig(const Strings_t &modules, const string &userModule)
main entry point of this class:
The ISvcLocator is the interface implemented by the Service Factory in the Application Manager to loc...
The data converters are responsible to translate data from one representation into another...
virtual const std::vector< Property * > & getProperties() const =0
Get list of properties.
virtual std::string toString() const =0
value -> string
std::vector< std::string > Strings_t
const std::string & name() const
property name
-*- C++ -*- /////////////////////////////
int genComponent(const std::string &libName, const std::string &componentName, const std::string &componentType, const vector< Property * > &properties)
void pythonizeValue(const Property *prop, string &pvalue, string &ptype)
handle the "marshalling" of Properties
static Time current(void)
Returns the current time.
GAUDI_API const std::string typeinfoName(const std::type_info &)
Get platform independent information about the class type.
void pythonizeName(string &name)
Translates a valid C++ typename into a valid python one.
void setConfigurableDefaultName(const std::string &defaultName)
customize the default name for configurable instances
GAUDIPS_API Logger & logger()
Return the current logger instance.
std::vector< fs::path > LibPathNames_t
GAUDI_API const std::string & moduleName()
Get the name of the (executable/DLL) file without file-type.
void setConfigurableAlgTool(const std::string &cfgAlgTool)
customize the configurable base class for AlgTool component
void * ImageHandle
Definition of an image handle.
GAUDI_API long argc()
Number of arguments passed to the commandline (==numCmdLineArgs()); just to match argv call...
GaudiUtils::HashMap< std::string, std::string > m_configurable
Configurable customization.
stringstream m_pyBuf
buffer of auto-generated configurables
void setConfigurableModule(const std::string &moduleName)
customize the Module name where configurable base classes are defined
int main(int argc, char **argv)
GAUDI_API ISvcLocator * svcLocator()
General service interface definition.
Definition of the basic interface.
virtual StatusCode setProperty(const Property &p)=0
Set the property by property.
GAUDI_API bool isEnvSet(const char *var)
Check if an environment variable is set or not.
virtual const std::string pythonRepr() const
Python representation of handle, i.e.
GAUDI_API std::string getEnv(const char *var)
get a particular environment variable (returning "UNKNOWN" if not set)
void genHeader(std::ostream &pyOut, std::ostream &dbOut)
stringstream m_dbBuf
buffer of generated configurables informations for the "Db" file The "Db" file is holding information...
configGenerator(const string &pkgName, const string &outputDirName)
The IAlgorithm is the interface implemented by the Algorithm base class.
void setConfigurableAlgorithm(const std::string &cfgAlgorithm)
customize the configurable base class for Algorithm component
void reset(TYPE *ptr=0)
Set the internal pointer to the passed one disposing of the old one.
void init_logging(boost::log::trivial::severity_level level)
Base class of array's of various gaudihandles.
string m_outputDirName
absolute path to the directory where genconf will store auto-generated files (Configurables and Confi...
Property base class allowing Property* collections to be "homogeneous".
GAUDIPS_API void SetDebug(int debugLevel)
Backward compatibility with Reflex.
virtual unsigned long release()=0
Release Interface instance.
bool isValid() const
Allow for check if smart pointer is valid.
void genImport(std::ostream &s, const boost::format &frmt, std::string indent)
bool m_importGaudiHandles
switch to decide if the generated configurables need to import GaudiHandles (ie: if one of the compon...
void setConfigurableService(const std::string &cfgService)
customize the configurable base class for Service component
const GaudiHandleBase & value() const
GAUDI_API const std::string getLastErrorString()
Get last system error as string.
In-memory database of the loaded factories.
string m_pkgName
name of the package we are processing
GAUDI_API unsigned long loadDynamicLib(const std::string &name, ImageHandle *handle)
Load dynamic link library.
virtual unsigned long addRef()=0
Increment the reference count of Interface instance.
static GAUDI_API void disableChecking()
const std::type_info * type_info() const
property type-info
void genTrailer(std::ostream &pyOut, std::ostream &dbOut)
Base class to handles to be used in lieu of naked pointers to various Gaudi components.
virtual StatusCode configure()=0
Configure the job.
Base class for all services.
A DataObject is the base class of any identifiable object on any data store.
The IAuditor is the interface implmented by the AlgAuditor base class.
virtual const std::string pythonRepr() const
Python representation of array of handles, i.e.
std::string libNativeName(const std::string &libName)
void genBody(std::ostream &pyOut, std::ostream &dbOut)
GAUDI_API std::string format(const char *,...)
MsgStream format utility "a la sprintf(...)".
std::string format(bool local, std::string spec="%c") const
Format the time using strftime.
GAUDI_API IAppMgrUI * createApplicationMgr(const std::string &dllname, const std::string &factname)
virtual void toStream(std::ostream &out) const =0
value -> stream
void setConfigurableAuditor(const std::string &cfgAuditor)
customize the configurable base class for AlgTool component