comparison OrthancFramework/Resources/CheckOrthancFrameworkSymbols.py @ 4277:c5ca798b158a

CheckOrthancFrameworkSymbols.py
author Sebastien Jodogne <s.jodogne@gmail.com>
date Tue, 03 Nov 2020 18:45:32 +0100
parents
children ab4d015af660
comparison
equal deleted inserted replaced
4276:68e24935f258 4277:c5ca798b158a
1 #!/usr/bin/env python
2
3 # Orthanc - A Lightweight, RESTful DICOM Store
4 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
5 # Department, University Hospital of Liege, Belgium
6 # Copyright (C) 2017-2020 Osimis S.A., Belgium
7 #
8 # This program is free software: you can redistribute it and/or
9 # modify it under the terms of the GNU Lesser General Public License
10 # as published by the Free Software Foundation, either version 3 of
11 # the License, or (at your option) any later version.
12 #
13 # This program is distributed in the hope that it will be useful, but
14 # WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 # Lesser General Public License for more details.
17 #
18 # You should have received a copy of the GNU Lesser General Public
19 # License along with this program. If not, see
20 # <http://www.gnu.org/licenses/>.
21
22
23 ##
24 ## This maintenance script detects all the public methods in the
25 ## Orthanc framework that come with an inlined implementation in the
26 ## header file. Such methods can break the ABI of the shared library,
27 ## as the actual implementation might change over versions.
28 ##
29
30
31 # Ubuntu 20.04:
32 # sudo apt-get install python-clang-6.0
33 # ./ParseWebAssemblyExports.py --libclang=libclang-6.0.so.1 ./Test.cpp
34
35 # Ubuntu 18.04:
36 # sudo apt-get install python-clang-4.0
37 # ./ParseWebAssemblyExports.py --libclang=libclang-4.0.so.1 ./Test.cpp
38
39 # Ubuntu 14.04:
40 # ./ParseWebAssemblyExports.py --libclang=libclang-3.6.so.1 ./Test.cpp
41
42
43 import os
44 import sys
45 import clang.cindex
46 import argparse
47
48 ##
49 ## Parse the command-line arguments
50 ##
51
52 parser = argparse.ArgumentParser(description = 'Parse WebAssembly C++ source file, and create a basic JavaScript wrapper.')
53 parser.add_argument('--libclang',
54 default = '',
55 help = 'manually provides the path to the libclang shared library')
56
57 args = parser.parse_args()
58
59
60 if len(args.libclang) != 0:
61 clang.cindex.Config.set_library_file(args.libclang)
62
63 index = clang.cindex.Index.create()
64
65
66 ROOT = os.path.abspath(os.path.dirname(sys.argv[0]))
67 SOURCES = []
68
69 for root, dirs, files in os.walk(os.path.join(ROOT, '..', 'Sources')):
70 for name in files:
71 if os.path.splitext(name)[1] == '.h':
72 SOURCES.append(os.path.join(root, name))
73
74 AMALGAMATION = '/tmp/CheckOrthancFrameworkSymbols.cpp'
75
76 with open(AMALGAMATION, 'w') as f:
77 f.write('#include "%s"\n' % os.path.join(ROOT, '..', 'Sources', 'OrthancFramework.h'))
78 for source in SOURCES:
79 f.write('#include "%s"\n' % source)
80
81
82 tu = index.parse(AMALGAMATION,
83 [ '-DORTHANC_BUILDING_FRAMEWORK_LIBRARY=1' ])
84
85
86
87 def ExploreNamespace(node, namespace):
88 for child in node.get_children():
89 fqn = namespace + [ child.spelling ]
90
91 if child.kind == clang.cindex.CursorKind.NAMESPACE:
92 ExploreNamespace(child, fqn)
93
94 elif (child.kind == clang.cindex.CursorKind.CLASS_DECL or
95 child.kind == clang.cindex.CursorKind.STRUCT_DECL):
96 visible = False
97
98 for i in child.get_children():
99 if (i.kind == clang.cindex.CursorKind.VISIBILITY_ATTR and
100 i.spelling == 'default'):
101 visible = True
102
103 if visible:
104 isPublic = (child.kind == clang.cindex.CursorKind.STRUCT_DECL)
105
106 for i in child.get_children():
107 if i.kind == clang.cindex.CursorKind.CXX_ACCESS_SPEC_DECL:
108 isPublic = (i.access_specifier == clang.cindex.AccessSpecifier.PUBLIC)
109
110 elif (i.kind == clang.cindex.CursorKind.CXX_METHOD or
111 i.kind == clang.cindex.CursorKind.CONSTRUCTOR):
112 if isPublic:
113 hasImplementation = False
114 for j in i.get_children():
115 if j.kind == clang.cindex.CursorKind.COMPOUND_STMT:
116 hasImplementation = True
117
118 if hasImplementation:
119 print('Exported public method with an implementation: %s::%s()' %
120 ('::'.join(fqn), i.spelling))
121
122
123 for node in tu.cursor.get_children():
124 if (node.kind == clang.cindex.CursorKind.NAMESPACE and
125 node.spelling == 'Orthanc'):
126 ExploreNamespace(node, [ 'Orthanc' ])