Source code

Revision control

Other Tools

1
#!/usr/bin/python3
2
# This Source Code Form is subject to the terms of the Mozilla Public
3
# License, v. 2.0. If a copy of the MPL was not distributed with this
4
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
5
6
import os
7
import sys
8
import glob
9
import shutil
10
import errno
11
12
import ThirdPartyPaths
13
14
15
def copy_dir_contents(src, dest):
16
for f in glob.glob("%s/*" % src):
17
try:
18
destname = "%s/%s" % (dest, os.path.basename(f))
19
if os.path.isdir(f):
20
shutil.copytree(f, destname)
21
else:
22
shutil.copy2(f, destname)
23
except OSError as e:
24
if e.errno == errno.ENOTDIR:
25
shutil.copy2(f, destname)
26
elif e.errno == errno.EEXIST:
27
if os.path.isdir(f):
28
copy_dir_contents(f, destname)
29
else:
30
os.remove(destname)
31
shutil.copy2(f, destname)
32
else:
33
raise Exception('Directory not copied. Error: %s' % e)
34
35
36
def write_cmake(module_path):
37
names = [' ' + os.path.basename(f) for f in glob.glob("%s/*.cpp" % module_path)]
38
with open(os.path.join(module_path, 'CMakeLists.txt'), 'w') as f:
39
f.write("""set(LLVM_LINK_COMPONENTS support)
40
41
add_definitions( -DCLANG_TIDY )
42
43
add_clang_library(clangTidyMozillaModule
44
ThirdPartyPaths.cpp
45
%(names)s
46
47
LINK_LIBS
48
clangAST
49
clangASTMatchers
50
clangBasic
51
clangLex
52
clangTidy
53
clangTidyReadabilityModule
54
clangTidyUtils
55
clangTidyMPIModule
56
)""" % {'names': "\n".join(names)})
57
58
59
def add_item_to_cmake_section(cmake_path, section, library):
60
with open(cmake_path, 'r') as f:
61
lines = f.readlines()
62
f.close()
63
64
libs = []
65
seen_target_libs = False
66
for line in lines:
67
if line.find(section) > -1:
68
seen_target_libs = True
69
elif seen_target_libs:
70
if line.find(')') > -1:
71
break
72
else:
73
libs.append(line.strip())
74
libs.append(library)
75
libs = sorted(libs, key=lambda s: s.lower())
76
77
with open(cmake_path, 'w') as f:
78
seen_target_libs = False
79
for line in lines:
80
if line.find(section) > -1:
81
seen_target_libs = True
82
f.write(line)
83
f.writelines([' ' + p + '\n' for p in libs])
84
continue
85
elif seen_target_libs:
86
if line.find(')') > -1:
87
seen_target_libs = False
88
else:
89
continue
90
f.write(line)
91
92
f.close()
93
94
95
def write_third_party_paths(mozilla_path, module_path):
96
tpp_txt = os.path.join(
97
mozilla_path, '../../tools/rewriting/ThirdPartyPaths.txt')
98
generated_txt = os.path.join(
99
mozilla_path, '../../tools/rewriting/Generated.txt')
100
with open(os.path.join(module_path, 'ThirdPartyPaths.cpp'), 'w') as f:
101
ThirdPartyPaths.generate(f, tpp_txt, generated_txt)
102
103
104
def do_import(mozilla_path, clang_tidy_path):
105
module = 'mozilla'
106
module_path = os.path.join(clang_tidy_path, module)
107
try:
108
os.makedirs(module_path)
109
except OSError as e:
110
if e.errno != errno.EEXIST:
111
raise
112
113
copy_dir_contents(mozilla_path, module_path)
114
write_third_party_paths(mozilla_path, module_path)
115
write_cmake(module_path)
116
add_item_to_cmake_section(os.path.join(module_path, '..', 'plugin',
117
'CMakeLists.txt'),
118
'LINK_LIBS', 'clangTidyMozillaModule')
119
add_item_to_cmake_section(os.path.join(module_path, '..', 'tool',
120
'CMakeLists.txt'),
121
'PRIVATE', 'clangTidyMozillaModule')
122
with open(os.path.join(module_path, '..', 'CMakeLists.txt'), 'a') as f:
123
f.write('add_subdirectory(%s)\n' % module)
124
with open(os.path.join(module_path, '..', 'tool', 'ClangTidyMain.cpp'), 'a') as f:
125
f.write('''
126
// This anchor is used to force the linker to link the MozillaModule.
127
extern volatile int MozillaModuleAnchorSource;
128
static int LLVM_ATTRIBUTE_UNUSED MozillaModuleAnchorDestination =
129
MozillaModuleAnchorSource;
130
''')
131
132
133
def main():
134
if len(sys.argv) != 3:
135
print("""\
136
Usage: import_mozilla_checks.py <mozilla-clang-plugin-path> <clang-tidy-path>
137
Imports the Mozilla static analysis checks into a clang-tidy source tree.
138
""")
139
140
return
141
142
mozilla_path = sys.argv[1]
143
if not os.path.isdir(mozilla_path):
144
print("Invalid path to mozilla clang plugin")
145
146
clang_tidy_path = sys.argv[2]
147
if not os.path.isdir(mozilla_path):
148
print("Invalid path to clang-tidy source directory")
149
150
do_import(mozilla_path, clang_tidy_path)
151
152
153
if __name__ == '__main__':
154
main()