ATLAS Offline Software
Loading...
Searching...
No Matches
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__ = """\
13helper script to generate header and cxx files of various athena
14components (svc/tool/alg/isvc/itool/object)
15"""
16
17import os
18from datetime import datetime
19
20import PyUtils.acmdlib as acmdlib
21
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
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 **/
48class %(klass)s : virtual public IService {
49public:
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 **/
73class %(klass)s : virtual public IAlgTool {
74public:
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 **/
98class %(klass)s {
99public:
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 **/
141class %(klass)s : public extends<AthService, %(iklass)s> {
142public:
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
149private:
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
171StatusCode %(klass)s::initialize()
172{
173 //ATH_MSG_DEBUG("Use macros for logging!");
174 return StatusCode::SUCCESS;
175}
176
177StatusCode %(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 **/
199class %(klass)s : public AthAlgorithm {
200public:
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
208private:
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
231StatusCode %(klass)s::initialize()
232{
233 //ATH_MSG_DEBUG("Use macros for logging!");
234 return StatusCode::SUCCESS;
235}
236
237StatusCode %(klass)s::finalize()
238{
239 return StatusCode::SUCCESS;
240}
241
242StatusCode %(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 **/
266class %(klass)s : public AthReentrantAlgorithm {
267public:
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
275private:
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
298StatusCode %(klass)s::initialize()
299{
300 //ATH_MSG_DEBUG("Use macros for logging!");
301 return StatusCode::SUCCESS;
302}
303
304StatusCode %(klass)s::finalize()
305{
306 return StatusCode::SUCCESS;
307}
308
309StatusCode %(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 **/
336class %(klass)s : public extends<AthAlgTool, %(iklass)s> {
337public:
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
344private:
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
367StatusCode %(klass)s::initialize()
368{
369 //ATH_MSG_DEBUG("Use macros for logging!");
370 return StatusCode::SUCCESS;
371}
372
373StatusCode %(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
392import AthenaCommon.SystemOfUnits as Units
393import AthenaPython.PyAthena as PyAthena
394from AthenaPython.PyAthena import StatusCode
395
396class %(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
433import AthenaCommon.SystemOfUnits as Units
434import AthenaPython.PyAthena as PyAthena
435from AthenaPython.PyAthena import StatusCode
436
437class %(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
471import AthenaCommon.SystemOfUnits as Units
472import AthenaPython.PyAthena as PyAthena
473from AthenaPython.PyAthena import StatusCode
474
475class %(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
509import AthenaCommon.SystemOfUnits as Units
510import AthenaPython.PyAthena as PyAthena
511from AthenaPython.PyAthena import StatusCode
512
513class %(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
535def 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
588def 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'))")
652def 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
gen_files(pkg="", klass="", klass_type='object', fname='foo', ipkg="", iklass="")
Definition gen_klass.py:536
gen_pyfiles(pkg="", klass="", klass_type='pyalg', fname='foo')
Definition gen_klass.py:588