Mercurial > hg > orthanc
comparison OrthancFramework/Resources/CheckOrthancFrameworkSymbols.py @ 4520:f5cb0c0ffbed
added unit test OrthancFramework.SizeOf to dump sizeof all the public classes in the Orthanc framework
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Mon, 22 Feb 2021 18:30:31 +0100 |
parents | d9473bd5ed43 |
children | 1de2fc0363cb |
comparison
equal
deleted
inserted
replaced
4519:a3c6678aa7b1 | 4520:f5cb0c0ffbed |
---|---|
51 | 51 |
52 parser = argparse.ArgumentParser(description = 'Parse WebAssembly C++ source file, and create a basic JavaScript wrapper.') | 52 parser = argparse.ArgumentParser(description = 'Parse WebAssembly C++ source file, and create a basic JavaScript wrapper.') |
53 parser.add_argument('--libclang', | 53 parser.add_argument('--libclang', |
54 default = '', | 54 default = '', |
55 help = 'manually provides the path to the libclang shared library') | 55 help = 'manually provides the path to the libclang shared library') |
56 parser.add_argument('--target-cpp-size', | |
57 default = '', | |
58 help = 'where to store C++ source to display the size of each public class') | |
56 | 59 |
57 args = parser.parse_args() | 60 args = parser.parse_args() |
58 | 61 |
59 | 62 |
60 if len(args.libclang) != 0: | 63 if len(args.libclang) != 0: |
105 ]) | 108 ]) |
106 | 109 |
107 | 110 |
108 FILES = [] | 111 FILES = [] |
109 COUNT = 0 | 112 COUNT = 0 |
113 ALL_TYPES = [] | |
110 | 114 |
111 def ReportProblem(message, fqn, cursor): | 115 def ReportProblem(message, fqn, cursor): |
112 global FILES, COUNT | 116 global FILES, COUNT |
113 FILES.append(os.path.normpath(str(cursor.location.file))) | 117 FILES.append(os.path.normpath(str(cursor.location.file))) |
114 COUNT += 1 | 118 COUNT += 1 |
139 visible = True | 143 visible = True |
140 | 144 |
141 if not visible: | 145 if not visible: |
142 return | 146 return |
143 | 147 |
148 global ALL_TYPES | |
149 ALL_TYPES.append('::'.join(fqn)) | |
150 | |
144 | 151 |
145 ## | 152 ## |
146 ## Ignore pure abstract interfaces, by checking the following | 153 ## Ignore pure abstract interfaces, by checking the following |
147 ## criteria: | 154 ## criteria: |
148 ## - It must be a C++ class (not a struct) | 155 ## - It must be a C++ class (not a struct) |
204 ## We are facing a standard C++ class or struct | 211 ## We are facing a standard C++ class or struct |
205 ## | 212 ## |
206 | 213 |
207 isPublic = (child.kind == clang.cindex.CursorKind.STRUCT_DECL) | 214 isPublic = (child.kind == clang.cindex.CursorKind.STRUCT_DECL) |
208 | 215 |
216 membersCount = 0 | |
217 membersSize = 0 | |
218 | |
209 for i in child.get_children(): | 219 for i in child.get_children(): |
210 if (i.kind == clang.cindex.CursorKind.VISIBILITY_ATTR or # "default" | 220 if (i.kind == clang.cindex.CursorKind.VISIBILITY_ATTR or # "default" |
211 i.kind == clang.cindex.CursorKind.CXX_BASE_SPECIFIER): # base class | 221 i.kind == clang.cindex.CursorKind.CXX_BASE_SPECIFIER): # base class |
212 pass | 222 pass |
213 | 223 |
230 | 240 |
231 if hasImplementation: | 241 if hasImplementation: |
232 ReportProblem('Exported public method with an implementation', fqn, i) | 242 ReportProblem('Exported public method with an implementation', fqn, i) |
233 | 243 |
234 elif i.kind == clang.cindex.CursorKind.VAR_DECL: | 244 elif i.kind == clang.cindex.CursorKind.VAR_DECL: |
235 if isPublic: | 245 raise Exception('Unsupported: %s, %s' % (i.kind, i.location)) |
236 ReportProblem('Exported public member variable', fqn, i) | |
237 | 246 |
238 elif i.kind == clang.cindex.CursorKind.FUNCTION_TEMPLATE: | 247 elif i.kind == clang.cindex.CursorKind.FUNCTION_TEMPLATE: |
239 # An inline function template is OK, as it is not added to | 248 # An inline function template is OK, as it is not added to |
240 # a shared library, but compiled by the client of the library | 249 # a shared library, but compiled by the client of the library |
241 if isPublic: | 250 if isPublic: |
259 not children[0].displayname in [ | 268 not children[0].displayname in [ |
260 # This is supported for ABI compatibility with Orthanc <= 1.8.0 | 269 # This is supported for ABI compatibility with Orthanc <= 1.8.0 |
261 'operator<<(std::ostream &, const Orthanc::DicomTag &)', | 270 'operator<<(std::ostream &, const Orthanc::DicomTag &)', |
262 ])): | 271 ])): |
263 raise Exception('Unsupported: %s, %s' % (i.kind, i.location)) | 272 raise Exception('Unsupported: %s, %s' % (i.kind, i.location)) |
273 | |
274 elif i.kind == clang.cindex.CursorKind.FIELD_DECL: | |
275 # TODO | |
276 if i.type.get_size() > 0: | |
277 membersSize += i.type.get_size() | |
278 membersCount += 1 | |
264 | 279 |
265 else: | 280 else: |
266 if isPublic: | 281 if isPublic: |
267 raise Exception('Unsupported: %s, %s' % (i.kind, i.location)) | 282 raise Exception('Unsupported: %s, %s' % (i.kind, i.location)) |
283 | |
284 #print('Size of %s => (%d,%d)' % ('::'.join(fqn), membersCount, membersSize)) | |
268 | 285 |
269 | 286 |
270 def ExploreNamespace(node, namespace): | 287 def ExploreNamespace(node, namespace): |
271 for child in node.get_children(): | 288 for child in node.get_children(): |
272 fqn = namespace + [ child.spelling ] | 289 fqn = namespace + [ child.spelling ] |
299 if (node.kind == clang.cindex.CursorKind.NAMESPACE and | 316 if (node.kind == clang.cindex.CursorKind.NAMESPACE and |
300 node.spelling == 'Orthanc'): | 317 node.spelling == 'Orthanc'): |
301 ExploreNamespace(node, [ 'Orthanc' ]) | 318 ExploreNamespace(node, [ 'Orthanc' ]) |
302 | 319 |
303 | 320 |
321 if args.target_cpp_size != '': | |
322 with open(args.target_cpp_size, 'w') as f: | |
323 for t in sorted(ALL_TYPES): | |
324 f.write(' printf("sizeof(::%s) == %%d\\n", static_cast<int>(sizeof(::%s)));\n' % (t, t)) | |
325 | |
326 | |
304 print('\nTotal of possibly problematic methods: %d' % COUNT) | 327 print('\nTotal of possibly problematic methods: %d' % COUNT) |
305 | 328 |
306 print('\nProblematic files:\n') | 329 print('\nProblematic files:\n') |
307 for i in sorted(list(set(FILES))): | 330 for i in sorted(list(set(FILES))): |
308 print(i) | 331 print(i) |