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
102
103
104
|
# this code was written to work, not to be maintained
# don't touch my trash
import os
import json
from extractor import parse_file
from parser import parse_definition_tokens
from symbols import symbols_from_struct_tokens, symbols_from_enum_tokens
stdlibs = [
"stdlib.h", "assert.h", "stdio.h", "stdint.h",
"inttypes.h", "mman.h", "stdatomic.h", "string.h", "unistd.h",
"fcntl.h", "pthread.h"
]
files_content = {
"stdbool.h": {
"symbols": ["bool"],
"usage": [],
"imports": []
}
}
def handle(file):
files_content[file] = {}
file_symbols = ["int", "char"]
definitions, _ = parse_file(root + "/" + file)
structs, enums, functions, typedefs, imports, usage = \
parse_definition_tokens(
definitions,
file_symbols
)
file_symbols.extend(symbols_from_struct_tokens(structs))
file_symbols.extend(symbols_from_struct_tokens(structs))
file_symbols.extend(symbols_from_enum_tokens(enums))
file_symbols.extend(functions)
file_symbols.extend(typedefs)
files_content[file]["symbols"] = set()
files_content[file]["imports"] = list(map(lambda x: x[1:-1] ,imports))
files_content[file]["usage"] = usage
for item in file_symbols:
if item.isnumeric():
continue
if "".join(item.split("_")).isalnum():
files_content[file]["symbols"].add(item)
for root, subdirs, files in os.walk("include"):
for file in files:
handle(file)
for root, subdirs, files in os.walk("src"):
for file in files:
handle(file)
for file in files_content.keys():
final_imports = set()
to_resolve = []
for imported_file in files_content[file]["imports"]:
x = imported_file.split("/")[-1]
to_resolve.append(x)
final_imports.add(x)
while len(to_resolve) > 0:
f = to_resolve.pop()
if f not in files_content:
if f not in stdlibs:
print(f)
assert f in stdlibs
continue
new_items = files_content[f]["imports"]
for new_item in new_items:
x = new_item.split("/")[-1]
to_resolve.append(x)
final_imports.add(x)
files_content[file]["imports"] = final_imports
for file, file_content in files_content.items():
symbols = list(file_content["symbols"])
for imported_file in file_content["imports"]:
imported_file = imported_file.split("/")[-1]
if imported_file not in files_content:
assert imported_file in stdlibs
continue
symbols.extend(files_content[imported_file]["symbols"])
symbols = set(symbols)
usage_set = set(file_content["usage"])
files_content[file]["unused"] = symbols - usage_set
files_content[file]["used"] = symbols.intersection(usage_set)
output = []
for file in files_content.keys():
output.append({
"name": file,
"imports": list(files_content[file]["imports"]),
"symbols": list(files_content[file]["symbols"]),
"unused": list(files_content[file]["unused"]),
"used": list(files_content[file]["used"])
})
with open("symbol_analyzer/analysis.js", "w") as f:
f.write("data = ")
json.dump(output, f)
|