ATLAS Offline Software
gen_klass.py
Go to the documentation of this file.
1 # Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
2 
3 # @file PyUtils.scripts.gen_klass.py
4 # @purpose helper script to generate header and cxx files of various
5 # athena components (svc/tool/alg/isvc/itool/object)
6 # @author Sebastien Binet
7 # @date April 2008
8 #
9 # Use PyUtils/test/test_genklass.sh to check compilation of generated code
10 
11 __author__ = "Sebastien Binet"
12 __doc__ = """\
13 helper script to generate header and cxx files of various athena
14 components (svc/tool/alg/isvc/itool/object)
15 """
16 
17 import os
18 from datetime import datetime
19 
20 import PyUtils.acmdlib as acmdlib
21 
22 class GenTypes:
23  values = ('object',
24  'isvc', 'svc',
25  'itool', 'tool',
26  'alg', 'reentrant_alg',
27 
28  'pyalg', 'pysvc', 'pytool', 'pyaud'
29  )
30  needing_iface = ('svc', 'tool')
31  pass
32 
33 class Templates:
34  copyright_template = "Copyright (C) 2002-%d CERN for the benefit of the ATLAS collaboration" % datetime.now().year
35  isvc_hdr_template = """\
36 /*
37  %(copyright)s
38 */
39 #ifndef %(guard)s
40 #define %(guard)s
41 
42 #include "GaudiKernel/IService.h"
43 %(namespace_begin)s
44 /**
45  * @class %(klass)s
46  * @brief
47  **/
48 class %(klass)s : virtual public IService {
49 public:
50  DeclareInterfaceID(%(klass)s, 1, 0);
51 
52  virtual ~%(klass)s() override {}
53 };
54 %(namespace_end)s
55 #endif // %(guard)s
56 """
57 
58  isvc_cxx_template = ""
59 
60  itool_hdr_template = """\
61 /*
62  %(copyright)s
63 */
64 #ifndef %(guard)s
65 #define %(guard)s
66 
67 #include "GaudiKernel/IAlgTool.h"
68 %(namespace_begin)s
69 /**
70  * @class %(klass)s
71  * @brief
72  **/
73 class %(klass)s : virtual public IAlgTool {
74 public:
75  DeclareInterfaceID(%(klass)s, 1, 0);
76 
77  virtual ~%(klass)s() override {}
78 };
79 %(namespace_end)s
80 #endif // %(guard)s
81 """
82 
83  itool_cxx_template = ""
84 
85  object_hdr_template = """\
86 /*
87  %(copyright)s
88 */
89 #ifndef %(guard)s
90 #define %(guard)s
91 
92 #include <iosfwd>
93 %(namespace_begin)s
94 /**
95  * @class %(klass)s
96  * @brief
97  **/
98 class %(klass)s {
99 public:
100  %(klass)s();
101  %(klass)s(const %(klass)s& rhs);
102  %(klass)s& operator=(const %(klass)s& rhs);
103  virtual ~%(klass)s();
104 };
105 
106 //std::ostream& operator<<(std::ostream& out, const %(klass)s& o);
107 %(namespace_end)s
108 #endif // %(guard)s
109 """
110 
111  object_cxx_template = """\
112 /*
113  %(copyright)s
114 */
115 
116 #include "%(pkg)s/%(klass)s.h"
117 %(namespace_begin)s
118 %(namespace_end)s
119 """
120 
121  svc_hdr_template = """\
122 /*
123  %(copyright)s
124 */
125 #ifndef %(guard)s
126 #define %(guard)s
127 
128 // Package includes
129 #include "%(ipkg)s/%(iklass)s.h"
130 
131 // Framework includes
132 #include "AthenaBaseComps/AthService.h"
133 
134 // STL includes
135 #include <string>
136 %(namespace_begin)s
137 /**
138  * @class %(klass)s
139  * @brief
140  **/
141 class %(klass)s : public extends<AthService, %(iklass)s> {
142 public:
143  %(klass)s(const std::string& name, ISvcLocator* pSvcLocator);
144  virtual ~%(klass)s() override;
145 
146  virtual StatusCode initialize() override;
147  virtual StatusCode finalize() override;
148 
149 private:
150  //Gaudi::Property<int> m_myInt{this, "MyInt", 0, "An Integer"};
151 };
152 %(namespace_end)s
153 #endif // %(guard)s
154 """
155 
156  svc_cxx_template = """\
157 /*
158  %(copyright)s
159 */
160 #include "%(klass)s.h"
161 %(namespace_begin)s
162 %(klass)s::%(klass)s(const std::string& name, ISvcLocator* pSvcLocator) :
163  base_class(name, pSvcLocator)
164 {
165 }
166 
167 %(klass)s::~%(klass)s()
168 {
169 }
170 
171 StatusCode %(klass)s::initialize()
172 {
173  //ATH_MSG_DEBUG("Use macros for logging!");
174  return StatusCode::SUCCESS;
175 }
176 
177 StatusCode %(klass)s::finalize()
178 {
179  return StatusCode::SUCCESS;
180 }
181 %(namespace_end)s
182 """
183 
184  alg_hdr_template = """\
185 /*
186  %(copyright)s
187 */
188 #ifndef %(guard)s
189 #define %(guard)s
190 
191 #include "AthenaBaseComps/AthAlgorithm.h"
192 
193 #include <string>
194 %(namespace_begin)s
195 /**
196  * @class %(klass)s
197  * @brief
198  **/
199 class %(klass)s : public AthAlgorithm {
200 public:
201  %(klass)s(const std::string& name, ISvcLocator* pSvcLocator);
202  virtual ~%(klass)s() override;
203 
204  virtual StatusCode initialize() override;
205  virtual StatusCode execute() override;
206  virtual StatusCode finalize() override;
207 
208 private:
209  //Gaudi::Property<int> m_myInt{this, "MyInt", 0, "An Integer"};
210 };
211 %(namespace_end)s
212 #endif // %(guard)s
213 """
214 
215  alg_cxx_template = """\
216 /*
217  %(copyright)s
218 */
219 
220 #include "%(klass)s.h"
221 %(namespace_begin)s
222 %(klass)s::%(klass)s(const std::string& name, ISvcLocator* pSvcLocator) :
223  AthAlgorithm(name, pSvcLocator)
224 {
225 }
226 
227 %(klass)s::~%(klass)s()
228 {
229 }
230 
231 StatusCode %(klass)s::initialize()
232 {
233  //ATH_MSG_DEBUG("Use macros for logging!");
234  return StatusCode::SUCCESS;
235 }
236 
237 StatusCode %(klass)s::finalize()
238 {
239  return StatusCode::SUCCESS;
240 }
241 
242 StatusCode %(klass)s::execute()
243 {
244  return StatusCode::SUCCESS;
245 }
246 %(namespace_end)s
247 """
248 
249  reentrant_alg_hdr_template = """\
250 /*
251  %(copyright)s
252 */
253 #ifndef %(guard)s
254 #define %(guard)s
255 
256 // Framework includes
257 #include "AthenaBaseComps/AthReentrantAlgorithm.h"
258 
259 // STL includes
260 #include <string>
261 %(namespace_begin)s
262 /**
263  * @class %(klass)s
264  * @brief
265  **/
266 class %(klass)s : public AthReentrantAlgorithm {
267 public:
268  %(klass)s(const std::string& name, ISvcLocator* pSvcLocator);
269  virtual ~%(klass)s() override;
270 
271  virtual StatusCode initialize() override;
272  virtual StatusCode execute(const EventContext& context) const override;
273  virtual StatusCode finalize() override;
274 
275 private:
276  //Gaudi::Property<int> m_myInt{this, "MyInt", 0, "An Integer"};
277 };
278 %(namespace_end)s
279 #endif // %(guard)s
280 """
281 
282  reentrant_alg_cxx_template = """\
283 /*
284  %(copyright)s
285 */
286 
287 #include "%(klass)s.h"
288 %(namespace_begin)s
289 %(klass)s::%(klass)s(const std::string& name, ISvcLocator* pSvcLocator) :
290  AthReentrantAlgorithm(name, pSvcLocator)
291 {
292 }
293 
294 %(klass)s::~%(klass)s()
295 {
296 }
297 
298 StatusCode %(klass)s::initialize()
299 {
300  //ATH_MSG_DEBUG("Use macros for logging!");
301  return StatusCode::SUCCESS;
302 }
303 
304 StatusCode %(klass)s::finalize()
305 {
306  return StatusCode::SUCCESS;
307 }
308 
309 StatusCode %(klass)s::execute(const EventContext& context) const
310 {
311  return StatusCode::SUCCESS;
312 }
313 %(namespace_end)s
314 """
315 
316  tool_hdr_template = """\
317 /*
318  %(copyright)s
319 */
320 #ifndef %(guard)s
321 #define %(guard)s
322 
323 // Package includes
324 #include "%(ipkg)s/%(iklass)s.h"
325 
326 // Framework includes
327 #include "AthenaBaseComps/AthAlgTool.h"
328 
329 // STL includes
330 #include <string>
331 %(namespace_begin)s
332 /**
333  * @class %(klass)s
334  * @brief
335  **/
336 class %(klass)s : public extends<AthAlgTool, %(iklass)s> {
337 public:
338  %(klass)s(const std::string& type, const std::string& name, const IInterface* parent);
339  virtual ~%(klass)s() override;
340 
341  virtual StatusCode initialize() override;
342  virtual StatusCode finalize() override;
343 
344 private:
345  //Gaudi::Property<int> m_myInt{this, "MyInt", 0, "An Integer"};
346 };
347 %(namespace_end)s
348 #endif // %(guard)s
349 """
350 
351  tool_cxx_template = """\
352 /*
353  %(copyright)s
354 */
355 
356 #include "%(klass)s.h"
357 %(namespace_begin)s
358 %(klass)s::%(klass)s(const std::string& type, const std::string& name, const IInterface* parent) :
359  base_class(type, name, parent)
360 {
361 }
362 
363 %(klass)s::~%(klass)s()
364 {
365 }
366 
367 StatusCode %(klass)s::initialize()
368 {
369  //ATH_MSG_DEBUG("Use macros for logging!");
370  return StatusCode::SUCCESS;
371 }
372 
373 StatusCode %(klass)s::finalize()
374 {
375  return StatusCode::SUCCESS;
376 }
377 %(namespace_end)s
378 """
379 
380  pyalg_template = """\
381 #
382 # %(copyright)s
383 #
384 
385 # @file: %(pkg)s/python/%(fname)s
386 # @purpose: <put some purpose here>
387 # @author: Sebastien Binet <binet@cern.ch>
388 
389 __doc__ = 'some documentation here'
390 __author__ = 'Sebastien Binet <binet@cern.ch>'
391 
392 import AthenaCommon.SystemOfUnits as Units
393 import AthenaPython.PyAthena as PyAthena
394 from AthenaPython.PyAthena import StatusCode
395 
396 class %(klass)s (PyAthena.Alg):
397  'put some documentation here'
398  def __init__(self, name='%(klass)s', **kw):
399  ## init base class
400  kw['name'] = name
401  super(%(klass)s, self).__init__(**kw)
402 
403  ## properties and data members
404  #self.foo = kw.get('foo', 10) # default value
405  return
406 
407  def initialize(self):
408  self.msg.info('==> initialize...')
409  return StatusCode.Success
410 
411  def execute(self):
412  return StatusCode.Success
413 
414  def finalize(self):
415  self.msg.info('==> finalize...')
416  return StatusCode.Success
417 
418  # class %(klass)s
419 """
420 
421  pysvc_template = """\
422 #
423 # %(copyright)s
424 #
425 
426 # @file: %(pkg)s/python/%(fname)s
427 # @purpose: <put some purpose here>
428 # @author: Sebastien Binet <binet@cern.ch>
429 
430 __doc__ = 'some documentation here'
431 __author__ = 'Sebastien Binet <binet@cern.ch>'
432 
433 import AthenaCommon.SystemOfUnits as Units
434 import AthenaPython.PyAthena as PyAthena
435 from AthenaPython.PyAthena import StatusCode
436 
437 class %(klass)s (PyAthena.Svc):
438  'put some documentation here'
439  def __init__(self, name='%(klass)s', **kw):
440  ## init base class
441  kw['name'] = name
442  super(%(klass)s, self).__init__(**kw)
443 
444  ## properties and data members
445  #self.foo = kw.get('foo', 10) # default value
446  return
447 
448  def initialize(self):
449  self.msg.info('==> initialize...')
450  return StatusCode.Success
451 
452  def finalize(self):
453  self.msg.info('==> finalize...')
454  return StatusCode.Success
455 
456  # class %(klass)s
457 """
458 
459  pytool_template = """\
460 #
461 # %(copyright)s
462 #
463 
464 # @file: %(pkg)s/python/%(fname)s
465 # @purpose: <put some purpose here>
466 # @author: Sebastien Binet <binet@cern.ch>
467 
468 __doc__ = 'some documentation here'
469 __author__ = 'Sebastien Binet <binet@cern.ch>'
470 
471 import AthenaCommon.SystemOfUnits as Units
472 import AthenaPython.PyAthena as PyAthena
473 from AthenaPython.PyAthena import StatusCode
474 
475 class %(klass)s (PyAthena.AlgTool):
476  'put some documentation here'
477  def __init__(self, name='%(klass)s', **kw):
478  ## init base class
479  kw['name'] = name
480  super(%(klass)s, self).__init__(**kw)
481 
482  ## properties and data members
483  #self.foo = kw.get('foo', 10) # default value
484  return
485 
486  def initialize(self):
487  self.msg.info('==> initialize...')
488  return StatusCode.Success
489 
490  def finalize(self):
491  self.msg.info('==> finalize...')
492  return StatusCode.Success
493 
494  # class %(klass)s
495 """
496 
497  pyaud_template = """\
498 #
499 # %(copyright)s
500 #
501 
502 # @file: %(pkg)s/python/%(fname)s
503 # @purpose: <put some purpose here>
504 # @author: Sebastien Binet <binet@cern.ch>
505 
506 __doc__ = 'some documentation here'
507 __author__ = 'Sebastien Binet <binet@cern.ch>'
508 
509 import AthenaCommon.SystemOfUnits as Units
510 import AthenaPython.PyAthena as PyAthena
511 from AthenaPython.PyAthena import StatusCode
512 
513 class %(klass)s (PyAthena.Aud):
514  'put some documentation here'
515  def __init__(self, name='%(klass)s', **kw):
516  ## init base class
517  kw['name'] = name
518  super(%(klass)s, self).__init__(**kw)
519 
520  ## properties and data members
521  #self.foo = kw.get('foo', 10) # default value
522  return
523 
524  def initialize(self):
525  self.msg.info('==> initialize...')
526  return StatusCode.Success
527 
528  def finalize(self):
529  self.msg.info('==> finalize...')
530  return StatusCode.Success
531 
532  # class %(klass)s
533 """
534 
535 def gen_files(pkg="", klass="", klass_type='object', fname='foo',
536  ipkg="", iklass=""):
537  """Simple helper function to generate files based off some informations
538  @param pkg the name of the package holding the class we want to generate
539  @param klass the (fully qualified) name of the C++ class to generate
540  @param klass_type the type of class to generate (svc/tool/alg/object)
541  @param fname the filename to generate
542  @param ipkg the name of the package holding the interface of the class
543  @param iklass the name of the interface of the class we generate
544  """
545  try:
546  hdr = getattr(Templates, '%s_hdr_template'%klass_type)
547  cxx = getattr(Templates, '%s_cxx_template'%klass_type)
548  except AttributeError as err:
549  print ("::: UNKNOWN klass_type [%s] !" % klass_type)
550  raise err
551 
552  namespace_klass = klass.replace('::','_')
553  namespace_begin,namespace_end = "",""
554  if klass.count("::")>0:
555  nm = klass.split("::")[0]
556  klass = klass.split("::")[1]
557  namespace_begin = os.linesep + "namespace %s {" % nm + os.linesep
558  namespace_end = os.linesep + "} // namespace %s" % nm + os.linesep
559  pass
560 
561  guard = "%s_%s_H" % (pkg.upper(), namespace_klass.upper())
562 
563  d = dict( pkg=pkg,
564  klass=klass,
565  ipkg=ipkg,
566  iklass=iklass,
567  guard=guard,
568  namespace_begin=namespace_begin,
569  namespace_end=namespace_end,
570  copyright=Templates.copyright_template
571  )
572  fname = os.path.splitext(fname)[0]
573 
574  o_hdr = open(fname+'.h', 'w')
575  o_hdr.writelines(hdr%d)
576  o_hdr.flush()
577  o_hdr.close()
578 
579  if len(cxx)>0:
580  o_cxx = open(fname+'.cxx', 'w')
581  o_cxx.writelines(cxx%d)
582  o_cxx.flush()
583  o_cxx.close()
584 
585  return 0
586 
587 
588 def gen_pyfiles(pkg="", klass="", klass_type='pyalg', fname='foo'):
589  """Simple helper function to generate (python) files based off some
590  user informations.
591  @param pkg the name of the package holding the class we want to generate
592  @param klass the name of the python class to generate
593  @param klass_type the type of class to generate (pysvc/pytool/pyalg/pyaud)
594  @param fname the filename to generate
595  """
596  try:
597  py_template = getattr(Templates, '%s_template'%klass_type)
598  except AttributeError as err:
599  print ("::: UNKNOWN klass_type [%s] !" % klass_type)
600  raise err
601 
602  invalid_py_chars = ( ':', '.', '>', '<', ' ' )
603 
604  if any([c for c in invalid_py_chars if c in klass]):
605  err = "::: INVALID class name ! (%s) !\n"%klass
606  err += "::: python class names can *NOT* contain any character of %s"%\
607  repr(invalid_py_chars)
608  print (err)
609  raise RuntimeError(err)
610 
611  fname=''.join([fname,'.py'])
612  d = dict( pkg=pkg,
613  klass=klass,
614  fname=fname,
615  copyright=Templates.copyright_template
616  )
617  o = open(fname, 'w')
618  o.writelines(py_template%d)
619  o.flush()
620  o.close()
621  return 0
622 
623 @acmdlib.command(name='gen-klass')
624 @acmdlib.argument(
625  "--klass",
626  required=True,
627  help = "The (fully qualified) name of the python or C++ class to create (ex: ElectronContainer, Analysis::Electron, MyAlgTool, PyTestAlg)")
628 @acmdlib.argument(
629  "--pkg",
630  required=True,
631  help = "The name of the package holding the C++ class to create (ex: MyAnalysis, JetEvent)")
632 @acmdlib.argument(
633  "--type",
634  dest = "klass_type",
635  required=True,
636  choices = GenTypes.values,
637  help = "The type of class to create")
638 @acmdlib.argument(
639  "--ipkg",
640  default = None,
641  help = "The name of the package holding the interface of the C++ class (mandatory for 'svc' and 'tool' types)")
642 @acmdlib.argument(
643  "--iklass",
644  default = None,
645  help = "The name of the interface the C++ class is implementing (mandatory for 'svc' and 'tool' types)")
646 @acmdlib.argument(
647  "-o",
648  "--output-file",
649  required=True,
650  dest = "fname",
651  help = "The name of the file(s) which will hold header and implementation of the class (ex: 'Foo' --> ('Foo.h','Foo.cxx'))")
652 def main(args):
653  """helper script to generate header and cxx files
654  of various athena components (svc/tool/alg/isvc/itool/object)
655  """
656 
657  exitcode = 0
658 
659  if args.klass_type in GenTypes.needing_iface and \
660  ( args.ipkg is None or args.iklass is None ) :
661  print (":: You have to give 'ipkg' and 'iklass' options to properly ",)
662  print ("generate an implementation for '%s'"%args.klass_type)
663  return 3
664 
665 
666  if args.ipkg is None:
667  args.ipkg = ""
668 
669  if args.iklass is None:
670  args.iklass = ""
671 
672  if args.klass_type.startswith('py'):
673  exitcode = gen_pyfiles(
674  klass=args.klass,
675  klass_type=args.klass_type,
676  pkg=args.pkg,
677  fname=args.fname
678  )
679  else:
680  exitcode = gen_files(
681  klass=args.klass,
682  klass_type=args.klass_type,
683  pkg=args.pkg,
684  iklass=args.iklass,
685  ipkg=args.ipkg,
686  fname=args.fname
687  )
688  return exitcode
python.scripts.gen_klass.GenTypes
Definition: gen_klass.py:22
python.scripts.gen_klass.gen_files
def gen_files(pkg="", klass="", klass_type='object', fname='foo', ipkg="", iklass="")
Definition: gen_klass.py:535
PyAthena::repr
std::string repr(PyObject *o)
returns the string representation of a python object equivalent of calling repr(o) in python
Definition: PyAthenaUtils.cxx:106
python.scripts.gen_klass.gen_pyfiles
def gen_pyfiles(pkg="", klass="", klass_type='pyalg', fname='foo')
Definition: gen_klass.py:588
TCS::join
std::string join(const std::vector< std::string > &v, const char c=',')
Definition: Trigger/TrigT1/L1Topo/L1TopoCommon/Root/StringUtils.cxx:10
python.scripts.gen_klass.Templates
Definition: gen_klass.py:33
Trk::open
@ open
Definition: BinningType.h:40
python.scripts.gen_klass.main
def main(args)
Definition: gen_klass.py:652