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"
75 namespace fs = boost::filesystem;
90 const boost::regex pythonIdentifier(
"^[a-zA-Z_][a-zA-Z0-9_]*$");
126 const string& outputDirName ) :
127 m_pkgName ( pkgName ),
128 m_outputDirName ( outputDirName ),
130 m_importGaudiHandles( false ),
131 m_importDataObjectHandles( false ),
151 m_configurable[
"DefaultName" ] = defaultName;
157 m_configurable[
"Algorithm" ] = cfgAlgorithm;
163 m_configurable[
"AlgTool" ] = cfgAlgTool;
169 m_configurable[
"Auditor" ] = cfgAuditor;
175 m_configurable[
"Service" ] = cfgService;
176 m_configurable[
"ApplicationMgr" ] = cfgService;
195 void pythonizeValue(
const Property* prop,
200 void pythonizeName(
string&
name );
216 po::options_description
generic(
"Generic options");
217 generic.add_options()
219 "produce this help message")
222 "name of the package for which we create the configurables file")
223 (
"input-libraries,i",
225 "libraries to extract the component configurables from")
228 "path to the cfg file holding the description of the Configurable base "
229 "classes, the python module holding the Configurable definitions, etc...")
231 po::value<string>()->default_value(
"../genConf"),
232 "output directory for genconf files.")
234 po::value<int>()->default_value(0),
237 po::value< Strings_t >()->composing(),
238 "preloading library")
241 "user-defined module to be imported by the genConf-generated one")
243 "do not generate the (empty) __init__.py")
248 po::options_description
config(
"Configuration");
250 (
"configurable-module",
251 po::value<string>()->default_value(
"AthenaCommon"),
252 "Name of the module holding the configurable classes")
253 (
"configurable-default-name",
254 po::value<string>()->default_value(
"Configurable.DefaultName"),
255 "Default name for the configurable instance")
256 (
"configurable-algorithm",
257 po::value<string>()->default_value(
"ConfigurableAlgorithm"),
258 "Name of the configurable base class for Algorithm components")
259 (
"configurable-algtool",
260 po::value<string>()->default_value(
"ConfigurableAlgTool"),
261 "Name of the configurable base class for AlgTool components")
262 (
"configurable-auditor",
263 po::value<string>()->default_value(
"ConfigurableAuditor"),
264 "Name of the configurable base class for Auditor components")
265 (
"configurable-service",
266 po::value<string>()->default_value(
"ConfigurableService"),
267 "Name of the configurable base class for Service components")
270 po::options_description cmdline_options;
271 cmdline_options.add(
generic).add(config);
273 po::options_description config_file_options;
274 config_file_options.add(config);
276 po::options_description visible(
"Allowed options");
277 visible.add(
generic).add(config);
279 po::variables_map vm;
282 po::store( po::command_line_parser(argc, argv).
283 options(cmdline_options).run(),
289 if( vm.count(
"input-cfg") ) {
290 string cfgFileName = vm[
"input-cfg"].as<
string>();
291 cfgFileName = fs::system_complete(
fs::path( cfgFileName ) ).
string();
293 po::store( parse_config_file( ifs, config_file_options ), vm );
298 catch ( po::error& err ) {
299 cout <<
"ERROR: error detected while parsing command options: "<< err.what() <<
endl;
304 if( vm.count(
"help")) {
309 if( vm.count(
"package-name") ) {
310 pkgName = vm[
"package-name"].as<
string>();
313 cout <<
"ERROR: 'package-name' required" <<
endl;
318 if( vm.count(
"user-module") ) {
319 userModule = vm[
"user-module"].as<
string>();
320 cout <<
"INFO: will import user module " << userModule <<
endl;
323 if( vm.count(
"input-libraries") ) {
329 string tmp = vm[
"input-libraries"].as<
string>();
331 boost::split( inputLibs, tmp,
332 boost::is_any_of(
" "),
333 boost::token_compress_on );
338 for ( Strings_t::const_iterator iLib = inputLibs.
begin();
339 iLib != inputLibs.
end();
342 if ( 0 == lib.
find(
"lib") ) {
351 if ( libs.
empty() ) {
352 cout <<
"ERROR: input component library(ies) required !\n"
353 <<
"ERROR: 'input-libraries' argument was ["
354 << vm[
"input-libraries"].as<
string>()
361 cout <<
"ERROR: input component library(ies) required" <<
endl;
366 if( vm.count(
"output-dir") ) {
367 out = fs::system_complete(
fs::path( vm[
"output-dir"].as<string>() ) );
370 if ( vm.count(
"debug-level") ) {
374 if ( vm.count(
"load-library") ) {
376 for (Strings_t::const_iterator lLib=lLib_list.
begin();
377 lLib != lLib_list.
end();
383 cout <<
"WARNING: failed to load: "<< *lLib <<
endl;
389 if ( !fs::exists( out ) ) {
391 fs::create_directory(out);
393 catch ( fs::filesystem_error &err ) {
394 cout <<
"ERROR: error creating directory: "<< err.what() <<
endl;
399 cout <<
":::::: libraries : [ ";
401 cout <<
"] ::::::" <<
endl;
405 py.setConfigurableDefaultName(vm[
"configurable-default-name"].as<string>());
406 py.setConfigurableAlgorithm (vm[
"configurable-algorithm"].as<string>());
407 py.setConfigurableAlgTool (vm[
"configurable-algtool"].as<string>());
408 py.setConfigurableAuditor (vm[
"configurable-auditor"].as<string>());
409 py.setConfigurableService (vm[
"configurable-service"].as<string>());
411 int sc = EXIT_FAILURE;
413 sc = py.genConfig( libs, userModule );
416 cout <<
"ERROR: Could not generate Configurable(s) !\n"
417 <<
"ERROR: Got exception: " << e.
what() <<
endl;
421 if ( EXIT_SUCCESS == sc && ! vm.count(
"no-init")) {
424 std::ios_base::out|std::ios_base::trunc );
425 initPy <<
"## Hook for " << pkgName <<
" genConf module\n" <<
flush;
428 cout <<
":::::: libraries : [ ";
430 cout <<
"] :::::: [DONE]" <<
endl;
442 const Strings_t::const_iterator endLib = libs.
end();
445 const bool isGaudiSvc = (
std::find( libs.
begin(), endLib, gaudiSvc ) != endLib );
449 cout <<
"ERROR: ApplicationMgr can not be created. Check environment" <<
endl;
455 Registry&
registry = Registry::instance();
466 for ( Strings_t::const_iterator iLib=libs.
begin(); iLib != endLib; ++iLib ) {
471 m_importGaudiHandles =
false;
472 m_importDataObjectHandles =
false;
488 it != factories.
end(); ++it ) {
489 const string ident = *it;
490 if ( bkgNames.
find(ident) != bkgNames.
end() ) {
492 cout <<
"\t==> skipping [" << ident <<
"]..." <<
endl;
497 const Registry::FactoryInfo info = registry.getInfo(*it);
498 const string rtype = info.rtype;
501 if (info.properties.find(
"ReflexName") != info.properties.end())
509 cout <<
"WARNING: library [" << *iLib <<
"] exposes factory ["
510 << ident <<
"] which is declared in ["
511 << DsoUtils::dsoName(info.ptr) <<
"] !!" <<
endl;
517 if ( ident ==
"ApplicationMgr" ) type =
"ApplicationMgr";
518 else if ( rtype ==
typeid(
IInterface*).
name() ) type =
"IInterface";
519 else if ( rtype ==
typeid(
IAlgorithm*).
name() ) type =
"Algorithm";
520 else if ( rtype ==
typeid(
IService* ).
name() ) type =
"Service";
521 else if ( rtype ==
typeid(
IAlgTool* ).
name() ) type =
"AlgTool";
522 else if ( rtype ==
typeid(
IAuditor* ).
name() ) type =
"Auditor";
523 else if ( rtype ==
typeid(
IConverter*).
name() ) type =
"Converter";
524 else if ( rtype ==
typeid(
DataObject*).
name() ) type =
"DataObject";
525 else type =
"Unknown", known =
false;
530 if ( type ==
"IInterface" ) {
536 if ( type ==
"Converter" || type ==
"DataObject" ) {
543 <<
" Component [" << ident <<
"] is skipped !"
548 cout <<
" - component: " << info.className <<
" (";
549 if (info.className != name)
550 cout << name <<
": ";
553 string cname =
"DefaultName";
556 if ( type ==
"Algorithm" ) {
559 else if ( type ==
"Service") {
562 else if ( type ==
"AlgTool") {
563 prop =
SmartIF<IAlgTool>(AlgTool::Factory::create(ident, cname, type, dummySvc));
567 else if ( type ==
"Auditor") {
570 else if ( type ==
"ApplicationMgr") {
578 cout <<
"ERROR: Error instantiating " << name
579 <<
" from " << *iLib <<
endl;
585 cout <<
"ERROR: Error instantiating " << name
586 <<
" from " << *iLib <<
endl;
591 if (genComponent( *iLib, name, type, prop->
getProperties() )) {
596 cout <<
"ERROR: could not cast IInterface* object to an IProperty* !\n"
597 <<
"ERROR: return type from PluginSvc is [" << rtype <<
"]...\n"
598 <<
"ERROR: NO Configurable will be generated for ["
609 fs::path(*iLib+
"Conf.py") ).
string();
611 fs::path(*iLib+
".confdb") ).
string();
613 std::fstream py( pyName, std::ios_base::out|std::ios_base::trunc );
614 std::fstream db( dbName, std::ios_base::out|std::ios_base::trunc );
616 genHeader ( py, db );
617 if (!userModule.
empty())
618 py <<
"from " << userModule <<
" import *" <<
endl;
620 genTrailer( py, db );
627 return allGood ? EXIT_SUCCESS : EXIT_FAILURE;
634 std::string::size_type pos = 0, nxtpos = 0;
637 while ( std::string::npos != pos ){
639 nxtpos = m_configurable[
"Module"].find_first_of(
',',pos);
642 mod = m_configurable[
"Module"].
substr(pos,nxtpos-pos);
648 if ( std::string::npos == nxtpos ) {
651 pos = std::string::npos;
655 <<
indent << py_tab <<
import.str() <<
"\n"
656 <<
indent <<
"except ImportError:\n"
673 <<
"\"\"\"Automatically generated. DO NOT EDIT please\"\"\"\n";
674 if ( m_importGaudiHandles ) {
675 py <<
"from GaudiKernel.GaudiHandles import *\n";
678 if ( m_importDataObjectHandles ) {
679 py <<
"from GaudiKernel.DataObjectHandleBase import *\n";
682 genImport(py,
boost::format(
"from %1%.Configurable import *"));
685 db <<
"## -*- ascii -*- \n"
686 <<
"# db file automatically generated by genconf on: "
697 db <<
"## " << m_pkgName <<
"\n"
709 string cname = componentName;
710 pythonizeName(cname);
713 PropertyDoc_t propDoc;
716 m_pyBuf <<
"class " << cname
717 <<
"( " << m_configurable[componentType] <<
" ) :"
719 m_pyBuf <<
" __slots__ = { \n";
721 it != properties.
end(); ++it ) {
723 const string pname = (*it)->name();
725 if (!boost::regex_match(pname, pythonIdentifier)) {
726 std::cout <<
"ERROR: invalid property name \"" << pname
727 <<
"\" in component " << cname
728 <<
" (invalid Python identifier)" <<
std::endl;
730 m_pyBuf <<
" #ERROR-invalid identifier '" << pname <<
"'\n"
735 string pvalue, ptype;
736 pythonizeValue( (*it), pvalue, ptype );
737 m_pyBuf <<
" '" << pname <<
"' : " << pvalue <<
", # " << ptype <<
"\n";
739 if ( (*it)->documentation() !=
"none" ) {
740 propDoc[
pname] = (*it)->documentation();
745 m_pyBuf <<
" _propertyDocDct = { \n";
746 for ( PropertyDoc_t::const_iterator iProp = propDoc.begin();
747 iProp != propDoc.end();
750 <<
"'" << iProp->first <<
"' : "
751 <<
"\"\"\" " << iProp->second <<
" \"\"\",\n";
756 <<
" def __init__(self, name = " << m_configurable[
"DefaultName"]
758 <<
" super(" << cname <<
", self).__init__(name)\n"
759 <<
" for n,v in kwargs.items():\n"
760 <<
" setattr(self, n, v)\n"
761 <<
" def getDlls( self ):\n"
762 <<
" return '" << libName <<
"'\n"
763 <<
" def getType( self ):\n"
764 <<
" return '" << componentName <<
"'\n"
765 <<
" pass # class " << cname <<
"\n"
769 const string pyName = (
fs::path(m_outputDirName) /
770 fs::path(libName+
"Conf.py") ).
string();
775 << m_pkgName <<
"." << modName <<
" "
776 << libName <<
" " << cname
786 static string in(
"<>&*,: ().");
787 static string out(
"__rp__s___");
788 boost::algorithm::replace_all(name,
", ",
",");
789 for ( string::iterator
i = name.
begin();
i != name.
end(); ++
i ) {
790 if ( in.
find(*
i) != string::npos ) *
i = out[in.
find(*
i)];
796 string& pvalue,
string& ptype )
801 if ( ti ==
typeid(
bool) ) {
802 pvalue = ( cvalue ==
"0" || cvalue ==
"False" || cvalue ==
"false" )
807 else if ( ti ==
typeid(
char) || ti ==
typeid(
signed char)
808 || ti ==
typeid(
unsigned char) ||
809 ti ==
typeid(short) || ti ==
typeid(
unsigned short) ||
810 ti ==
typeid(int) || ti ==
typeid(
unsigned int) ||
811 ti ==
typeid(long) || ti ==
typeid(
unsigned long) ) {
815 else if ( ti ==
typeid(
long long) || ti ==
typeid(
unsigned long long) ) {
816 pvalue = cvalue +
"L";
819 else if ( ti ==
typeid(
float) || ti ==
typeid(double) ) {
821 pvalue = boost::to_lower_copy(cvalue);
822 if ( pvalue ==
"nan" ) {
823 pvalue =
"float('nan')";
824 std::cout <<
"WARNING: default value for ["
825 << p->
name() <<
"] is NaN !!"
827 }
else if ( std::string::npos == pvalue.
find(
".") &&
828 std::string::npos == pvalue.
find(
"e") ) {
829 pvalue = cvalue +
".0";
833 else if ( ti ==
typeid(
string) ) {
835 pvalue =
"'"+cvalue+
"'";
839 m_importGaudiHandles =
true;
845 ptype =
"GaudiHandle";
848 m_importGaudiHandles =
true;
854 ptype =
"GaudiHandleArray";
857 m_importDataObjectHandles =
true;
863 ptype =
"DataObjectHandleBase";
867 v_str.
setf(std::ios::fixed);
869 pvalue = v_str.
str();
882 if ( !propMgr || !appUI )
return EXIT_FAILURE;
884 propMgr->setProperty(
"AppName",
"");
885 propMgr->setProperty(
"OutputLevel",
"7");
888 msgSvc->setProperty(
"setWarning",
"['DefaultName', 'PropertyMgr']");
889 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:
virtual std::string pythonRepr() const
Python representation of handle, i.e.
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...
const std::string pythonRepr() const
GAUDI_API std::string format(const char *,...)
MsgStream format utility "a la sprintf(...)".
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++ -*- /////////////////////////////
GAUDI_API const std::string typeinfoName(const std::type_info &)
Get platform independent information about the class type.
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.
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
std::vector< fs::path > LibPathNames_t
void setConfigurableAlgTool(const std::string &cfgAlgTool)
customize the configurable base class for AlgTool component
void * ImageHandle
Definition of an image handle.
GaudiUtils::HashMap< std::string, std::string > m_configurable
Configurable customization.
stringstream m_pyBuf
buffer of auto-generated configurables
GAUDIPS_API Logger & logger()
Return the current logger instance.
DataObjectHandleProperty.h GaudiKernel/DataObjectHandleProperty.h.
void setConfigurableModule(const std::string &moduleName)
customize the Module name where configurable base classes are defined
GAUDIPS_API void SetDebug(int debugLevel)
Backward compatibility with Reflex.
SmartIF< IFace > as() const
return a new SmartIF instance to another interface
int main(int argc, char **argv)
bool m_importDataObjectHandles
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.
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
GAUDI_API std::string path(const AIDA::IBaseHistogram *aida)
get the path in THS for AIDA histogram
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".
virtual unsigned long release()=0
Release Interface instance.
DataObjectHandleBase GaudiKernel/DataObjectHandleBase.h.
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
GAUDI_API const std::string & moduleName()
Get the name of the (executable/DLL) file without file-type.
const GaudiHandleBase & value() const
In-memory database of the loaded factories.
string m_pkgName
name of the package we are processing
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 reset(TYPE *ptr=nullptr)
Set the internal pointer to the passed one disposing of the old one.
void genTrailer(std::ostream &pyOut, std::ostream &dbOut)
const DataObjectHandleBase & value() const
GAUDI_API const std::string getLastErrorString()
Get last system error as string.
Base class to handles to be used in lieu of naked pointers to various Gaudi components.
virtual StatusCode configure()=0
Configure the job.
The IProperty is the basic interface for all components which have properties that can be set or get...
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.
std::string libNativeName(const std::string &libName)
void genBody(std::ostream &pyOut, std::ostream &dbOut)
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
GAUDI_API unsigned long loadDynamicLib(const std::string &name, ImageHandle *handle)
Load dynamic link library.
void setConfigurableAuditor(const std::string &cfgAuditor)
customize the configurable base class for AlgTool component
std::string pythonRepr() const override
Python representation of array of handles, i.e.