forked from ifsmirnov/jngen
-
Notifications
You must be signed in to change notification settings - Fork 0
/
build.py
executable file
·102 lines (78 loc) · 2.53 KB
/
build.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
#!/usr/bin/python3
import re, os
HEADER_REGEX = re.compile('#include "(.*)"')
# This list may contain not all headers directly, but each jngen header
# must be among the dependencies of some file from here.
LIBRARY_HEADERS = [
"array.h",
"random.h",
"common.h",
"tree.h",
"graph.h",
"geometry.h",
"math_jngen.h",
"rnda.h",
"rnds.h",
"testcases.h",
"options.h",
"printers.h",
"repr.h",
"query_builder.h",
"drawer/drawer.h",
"suites/suites.h",
]
def posix_path_to_native(posix_path):
return os.path.join(*posix_path.split('/'))
def extract_header(line):
res = HEADER_REGEX.match(line)
if res:
return res.groups()[0]
def extract_direct_deps(posix_filename):
dir = os.path.dirname(posix_filename) # check explicitly on win
res = set()
with open(posix_path_to_native(posix_filename)) as fin:
for line in fin.readlines():
t = extract_header(line)
if t and not t.endswith("_inl.h"):
res.add(dir + '/' + t if dir else t)
return res
deps = {}
def extract_deps(posix_filename):
posix_filename = os.path.normpath(posix_filename)
if posix_filename in deps:
return deps[posix_filename]
deps[posix_filename] = set((posix_filename,))
for dep in extract_direct_deps(posix_filename):
deps[posix_filename].update(extract_deps(dep))
return deps[posix_filename]
def write_file(filename, stream):
dir = os.path.dirname(filename) # check explicitly on win
with open(posix_path_to_native(filename)) as fin:
for line in fin.readlines():
include_or_not = HEADER_REGEX.match(line)
if include_or_not:
if include_or_not.groups()[0].endswith("_inl.h"):
t = include_or_not.groups()[0]
write_file(dir + '/' + t if dir else t, stream)
elif '#pragma once' not in line:
stream.write(line)
headers = set()
for h in LIBRARY_HEADERS:
headers.update(extract_deps(h))
headers = ['header.h'] + sorted(headers)
deps['footer.h'] = set(headers + ['footer.h'])
headers += ['footer.h']
deps['header.h'] = set(('header.h',))
headers_in_order = []
while headers:
for h in headers:
if len(deps[h]) == 1:
headers_in_order.append(h)
for other in deps:
deps[other].discard(h)
del deps[h]
headers.remove(h)
break
with open("jngen.h", "w") as fout:
for filename in headers_in_order:
write_file(filename, fout)