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