ATLAS Offline Software
Loading...
Searching...
No Matches
checkTP.py
Go to the documentation of this file.
1#!/usr/bin/env python
2
3# Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
4
5# @file: checkTP.py
6# @purpose: dump the layout of a class (data members and bases)
7# Inspired from SealDictTest/DictClassCheck.py from RD.
8# @author: Sebastien Binet <binet@cern.ch>
9# @date: September 2006
10#
11# @example:
12#
13# python checkTP.py TruthParticle
14#
15# if checkTP.py has been made 'chmod +x' one can just do:
16# ./checkTP.py CaloCellContainer
17
18import sys
19import os
20
21__author__ = "Sebastien Binet"
22
23# MN: this has no effect when using RootType
24S = 4 # SCOPED
25SF = 5 # SCOPED|FINAL
26SQ = 6 # SCOPED|QUALIFIED
27SFQ = 7 # SCOPED|FINAL|QUALIFIED
28DICTSCOPE = SF
29
30_cpp_builtins = (
31 'char', 'unsigned char', 'signed char',
32 'short', 'unsigned short',
33 'int', 'unsigned int',
34 'long', 'unsigned long',
35 'long long', 'unsigned long long', 'ulonglong',
36 'float',
37 'double',
38 'bool',
39 )
40
42 def __init__(self, offset, name, _type):
43 self.offset = offset
44 self.name = name
45 self.type = _type
46 return
47
49 def __init__(self, offset, name, _type):
50 self.name = name
51 self.type = _type
52 return
53
55
56 def __init__(self):
57 object.__init__(self)
58 print ("")
59 print ("#"*80)
60 print ("## initializing...")
61 import cppyy
62 self.gbl = cppyy.gbl
63 self.Type = cppyy.gbl.RootType
64
65 self.report = []
66 return
67
68 def loadDicts(self, klassName):
69 klassNames = [klassName]
70 print ("## loading dictionary... [%s]" % klassName)
71
72
73 if klassName.startswith("std::_"):
74 return klassNames
75 #return []
76
77
78 if klassName in _cpp_builtins:
79 return klassNames
80
81 loaded = False
82 try:
83 loaded = getattr (self.gbl, klassName)
84 except Exception as e:
85 print ("Error loading dict. for [%s]" % klassName)
86 print ("--> ", e)
87 if not loaded:
88 print ("Failed to load dict for [%s]" % klassName)
89 return klassNames
90 klass = self.Type.ByName(klassName)
91
92 if not klass.IsStruct() and not klass.IsClass():
93 return klassNames
94
95 for i in range(klass.BaseSize()):
96 baseKlassName = klass.BaseAt(i).Name()
97 klassNames.extend (self.loadDicts(baseKlassName))
98 pass
99
102 return klassNames
103
104 def dumpDataMembers(self, klass):
105 dataMembers = []
106 for i in range(klass.DataMemberSize()):
107 d = klass.DataMemberAt(i)
108 scope = klass.Name()
109 offset = '<s>' if d.IsStatic() else d.Offset()
110 fullname = '::'.join([scope, d.Name(SFQ)])
111 typename = d.TypeOf().Name(SFQ)
112 dataMembers.append( DataMember(offset, fullname, typename) )
113 return dataMembers
114
115 def dumpFctMembers(self, klass):
116 fctMembers = []
117 for i in range(klass.FunctionMemberSize()):
118 f = klass.FunctionMemberAt(i)
119 fctMembers.append( FctMember( f.Name(SFQ),
120 f.TypeOf().Name(SFQ) ) )
121 pass
122 return fctMembers
123
124 def inspect(self, klassName):
125 self.report = []
126 print ("")
127 print ("#"*80)
128 print ("## loading all relevant dictionaries...")
129 try:
130 klassNames = self.loadDicts(klassName)
131 print ("#"*80)
132 except Exception as err:
133 print ("")
134 print ("#"*80)
135 print ("## ERROR while trying to load dict for [%s]" % klassName)
136 print ("## -Most probably you DIDN'T give a fully qualified name !")
137 print ("## Ex: try 'Analysis::Muon' instead of 'Muon'")
138 print ("##")
139 print ("## -Could also mean that you are missing a dictionary ")
140 print ("## of one of the base classes...")
141 print ("#"*80)
142 print (err)
143 raise
144 return
145
146 print ("")
147 print ("#"*80)
148 print ("## infos for class [%s]:" % klassName)
149 print ("## sizeof(%s) = %i" % \
150 (klassName,
151 self.Type.SizeOf(self.Type.ByName(klassName))))
152 print ("##")
153 print ("## (offset, data member name, data member type)")
154 print ("")
155 # we want to dump from the base to the most derived class
156 klassNames.reverse()
157 for klass in klassNames:
158 line = "%s %s %s" % (
159 "-" * (40-len(klass)//2-1),
160 "[%s]" % klass,
161 "-" * (40-len(klass)//2-1) )
162
163 print (line)
164 self.report.append(line)
165 dataMembers = self.dumpDataMembers( self.Type.ByName(klass) )
166 for i in dataMembers:
167 line = "%3s %s %-50s %s %s" % ( str(i.offset),
168 " "*5,
169 i.name,
170 " "*5, i.type )
171 print (line)
172 self.report.append(line)
173 print ("#"*80)
174 return
175
176 def save(self, fileName = "./columbo.out" ):
177 file = open(os.path.expandvars(os.path.expanduser(fileName)),
178 "w+")
179 for line in self.report:
180 file.writelines(line + os.linesep)
181 pass
182 file.close()
183
184 pass # Columbo
185
186
187if __name__ == '__main__':
188 if len(sys.argv) > 1:
189 klassName = sys.argv[1]
190 else:
191 klassName = "xAOD::TruthParticle_v1"
192 pass
193
194 columbo = Columbo()
195 columbo.inspect(klassName)
196 columbo.save()
__init__(self)
Definition checkTP.py:56
loadDicts(self, klassName)
Definition checkTP.py:68
__init__(self, offset, name, _type)
Definition checkTP.py:42
__init__(self, offset, name, _type)
Definition checkTP.py:49
save(self, fileName="./columbo.out")
Definition checkTP.py:176
dumpFctMembers(self, klass)
Definition checkTP.py:115
dumpDataMembers(self, klass)
for i in xrange(klass.DataMemberSize()): mbr = klass.DataMemberAt(i).TypeOf().Name(DICTSCOPE) klassNa...
Definition checkTP.py:104
inspect(self, klassName)
Definition checkTP.py:124