-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathccollate.py
62 lines (48 loc) · 1.83 KB
/
ccollate.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
#!/usr/bin/env python
import os
import sys
import re
HEADER_EXTS = ['.h', '.hh', '.hpp']
include_dirs = ['.']
visited = set()
def parse(file_name):
if file_name in visited:
return ''
else:
visited.add(file_name)
with open(file_name, 'r') as file:
contents = file.read()
# Remove documentation comments
contents = re.sub(r'/\*\*(?:.|[\r\n])*?\*/\s*', '', contents)
contents = '\n'.join([line for line in contents.splitlines() if not line.strip().startswith('//')])
lines = contents.splitlines()
contents = []
for lineno, line in enumerate(lines, start=1):
if line.startswith('#include "'):
include_file = None
include_dirs.insert(0, os.path.dirname(file_name))
for inc in include_dirs:
include_path = os.path.abspath(os.path.join(inc, line.split('"')[1]))
if os.path.exists(include_path):
include_file = include_path
break
if include_file is None:
name = line.split('"')[1]
raise Exception(f"Fatal Error: The file {name} was not found in any of the include paths {include_dirs}")
include = parse(include_file)
include = f"#line {lineno + 1} \"{file_name}\"\n{include}"
contents.append(include)
else:
contents.append(line)
contents = '\n'.join(contents)
if contents:
contents = f"#line 1 \"{file_name}\"\n{contents}"
return contents
if len(sys.argv) == 1:
sys.exit(-1)
else:
start_file = os.path.abspath(sys.argv[1])
if not os.path.isfile(start_file) or os.path.splitext(start_file)[1] not in HEADER_EXTS:
raise Exception(f"{sys.argv[1]} is not a valid header file.")
include_dirs.append(os.path.dirname(start_file))
print(parse(start_file))