Mercurial > hg > orthanc
view OrthancFramework/Resources/CheckOrthancFrameworkSymbols.py @ 4301:6919242d2265
Fix keep-alive in the embedded HTTP server by setting the "Keep-Alive" HTTP header
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Fri, 06 Nov 2020 09:58:48 +0100 |
parents | b30a8de92ad9 |
children | 44b53a2c0a13 |
line wrap: on
line source
#!/usr/bin/env python # Orthanc - A Lightweight, RESTful DICOM Store # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics # Department, University Hospital of Liege, Belgium # Copyright (C) 2017-2020 Osimis S.A., Belgium # # This program is free software: you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public License # as published by the Free Software Foundation, either version 3 of # the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this program. If not, see # <http://www.gnu.org/licenses/>. ## ## This maintenance script detects all the public methods in the ## Orthanc framework that come with an inlined implementation in the ## header file. Such methods can break the ABI of the shared library, ## as the actual implementation might change over versions. ## # Ubuntu 20.04: # sudo apt-get install python-clang-6.0 # ./ParseWebAssemblyExports.py --libclang=libclang-6.0.so.1 ./Test.cpp # Ubuntu 18.04: # sudo apt-get install python-clang-4.0 # ./ParseWebAssemblyExports.py --libclang=libclang-4.0.so.1 ./Test.cpp # Ubuntu 14.04: # ./ParseWebAssemblyExports.py --libclang=libclang-3.6.so.1 ./Test.cpp import os import sys import clang.cindex import argparse ## ## Parse the command-line arguments ## parser = argparse.ArgumentParser(description = 'Parse WebAssembly C++ source file, and create a basic JavaScript wrapper.') parser.add_argument('--libclang', default = '', help = 'manually provides the path to the libclang shared library') args = parser.parse_args() if len(args.libclang) != 0: clang.cindex.Config.set_library_file(args.libclang) index = clang.cindex.Index.create() ROOT = os.path.abspath(os.path.dirname(sys.argv[0])) SOURCES = [] for root, dirs, files in os.walk(os.path.join(ROOT, '..', 'Sources')): for name in files: if os.path.splitext(name)[1] == '.h': SOURCES.append(os.path.join(root, name)) AMALGAMATION = '/tmp/CheckOrthancFrameworkSymbols.cpp' with open(AMALGAMATION, 'w') as f: f.write('#include "%s"\n' % os.path.join(ROOT, '..', 'Sources', 'OrthancFramework.h')) for source in SOURCES: f.write('#include "%s"\n' % source) tu = index.parse(AMALGAMATION, [ '-DORTHANC_BUILDING_FRAMEWORK_LIBRARY=1' ]) FILES = [] COUNT = 0 def ExploreClass(child, fqn): visible = False for i in child.get_children(): if (i.kind == clang.cindex.CursorKind.VISIBILITY_ATTR and i.spelling == 'default'): visible = True if visible: isPublic = (child.kind == clang.cindex.CursorKind.STRUCT_DECL) for i in child.get_children(): if i.kind == clang.cindex.CursorKind.CXX_ACCESS_SPEC_DECL: isPublic = (i.access_specifier == clang.cindex.AccessSpecifier.PUBLIC) elif (i.kind == clang.cindex.CursorKind.CLASS_DECL or i.kind == clang.cindex.CursorKind.STRUCT_DECL): # This is a subclass ExploreClass(i, fqn + [ i.spelling ]) elif (i.kind == clang.cindex.CursorKind.CXX_METHOD or i.kind == clang.cindex.CursorKind.CONSTRUCTOR or i.kind == clang.cindex.CursorKind.DESTRUCTOR): if isPublic: hasImplementation = False for j in i.get_children(): if j.kind == clang.cindex.CursorKind.COMPOUND_STMT: hasImplementation = True if hasImplementation: global FILES, COUNT FILES.append(os.path.normpath(str(child.location.file))) COUNT += 1 print('Exported public method with an implementation: %s::%s()' % ('::'.join(fqn), i.spelling)) def ExploreNamespace(node, namespace): for child in node.get_children(): fqn = namespace + [ child.spelling ] if child.kind == clang.cindex.CursorKind.NAMESPACE: ExploreNamespace(child, fqn) elif (child.kind == clang.cindex.CursorKind.CLASS_DECL or child.kind == clang.cindex.CursorKind.STRUCT_DECL): ExploreClass(child, fqn) for node in tu.cursor.get_children(): if (node.kind == clang.cindex.CursorKind.NAMESPACE and node.spelling == 'Orthanc'): ExploreNamespace(node, [ 'Orthanc' ]) print('\nTotal of possibly problematic methods: %d' % COUNT) print('\nFiles:\n') for i in sorted(list(set(FILES))): print(i)