Subversion Repositories Kolibri OS

Rev

Rev 8834 | Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
8825 Boppan 1
import os
2
from glob import glob
3
 
4
"""
5
# Collect all .inc files
6
kernel_files = [y for x in os.walk(".") for y in glob(os.path.join(x[0], '*.inc'))]
7
 
8
to_remove = []
9
for i in range(len(kernel_files)):
10
	inc = kernel_files[i]
11
	# Remove files that aren't a part of the kernel
12
	if "bootloader" in inc or "sec_loader" in inc:
13
		to_remove.append(i)
14
 
15
for i in range(len(to_remove) - 1, -1, -1):
16
	kernel_files.pop(to_remove[i])
17
 
18
# Add main kernel file
19
kernel_files.append("kernel.asm")
20
 
21
# Add main kernel file
22
# TODO: Rename the file so it won't be an exception
23
kernel_files.append("fs/xfs.asm")
24
"""
25
 
26
import re
27
 
28
# kernel_structure["filename"] = {
29
#   [ [],    # [0] Variables - [ line, name ]
30
#     [],    # [1] Macros - [ line, name ]
31
#     [],    # [2] Procedures - [ line, name ]
32
#     [],    # [3] Labels - [ line, name ]
33
#     [] ] } # [4] Structures - [ line, name ]
34
VARIABLES = 0
35
MACROS = 1
36
PROCEDURES = 2
37
LABELS = 3
38
STRUCTURES = 4
39
kernel_structure = {}
40
 
41
def get_declarations(asm_file_contents, asm_file_name):
42
	kernel_structure[asm_file_name] = [ [], [], [], [], [] ]
43
 
44
	variable_pattern = re.compile(r'^\s*([\w\.]+)\s+d[bwdq] .*')
45
	macro_pattern = re.compile(r'^\s*macro\s+([\w]+).*')
46
	proc_pattern = re.compile(r'^\s*proc\s+([\w\.]+).*')
47
	label_pattern = re.compile(r'^(?!;)\s*([\w\.]+):.*')
48
	struct_pattern = re.compile(r'^\s*struct\s+([\w]+).*')
49
 
50
	line_idx = 0
51
	lines = asm_file_contents.splitlines()
52
	while line_idx < len(lines):
53
		line = lines[line_idx]
54
 
55
		match = variable_pattern.findall(line)
56
		if len(match) > 0:
57
			var_name = match[0]
58
			#print(f"Variable '{var_name}' at {line_idx + 1}")
59
			kernel_structure[asm_file_name][VARIABLES].append([ line_idx + 1, var_name ])
60
			line_idx += 1
61
			continue
62
 
63
		match = macro_pattern.findall(line)
64
		if len(match) > 0:
65
			macro_name = match[0]
66
			#print(f"Macro '{macro_name}' at {line_idx + 1}")
67
			kernel_structure[asm_file_name][MACROS].append([ line_idx + 1, macro_name ])
68
			end_of_macro = False
69
			while not end_of_macro:
70
				line = lines[line_idx]
71
				rbraces = re.finditer('}', line)
72
				for rbrace_match in rbraces:
73
					rbrace_idx = rbrace_match.start()
74
					if line[rbrace_idx - 1] != '\\':
75
						end_of_macro = True
76
				line_idx += 1
77
			continue
78
 
79
		match = proc_pattern.findall(line)
80
		if len(match) > 0:
81
			proc_name = match[0]
82
			#print(f"Procedure '{proc_name}' at {line_idx + 1}")
83
			kernel_structure[asm_file_name][PROCEDURES].append([ line_idx + 1, proc_name ])
84
			line_idx += 1
85
			continue
86
 
87
		match = label_pattern.findall(line)
88
		if len(match) > 0:
89
			label_name = match[0]
90
			# Don't count local labels
91
			if label_name[0] != '.':
92
				#print(f"Label '{label_name}' at {line_idx + 1}")
93
				kernel_structure[asm_file_name][LABELS].append([ line_idx + 1, label_name ])
94
				line_idx += 1
95
				continue
96
 
97
		match = struct_pattern.findall(line)
98
		if len(match) > 0:
99
			struct_name = match[0]
100
			#print(f"Structure '{struct_name}' at {line_idx + 1}")
101
			kernel_structure[asm_file_name][STRUCTURES].append([ line_idx + 1, struct_name ])
102
			end_of_struct = False
103
			while not end_of_struct:
104
				line = lines[line_idx]
105
				if re.match(r"^ends$", line) != None:
106
					end_of_struct = True
107
				line_idx += 1
108
			continue
109
 
110
		line_idx += 1
111
 
112
def get_includes(handled_files, asm_file_name, subdir = "."):
113
	print(f"Handling {asm_file_name}")
114
	handled_files.append(asm_file_name)
115
	try:
116
		asm_file_contents = open(asm_file_name, "r", encoding="utf-8").read()
117
	except:
118
		return
119
	get_declarations(asm_file_contents, asm_file_name)
120
	include_directive_pattern_1 = re.compile(r'include "(.*)"')
121
	include_directive_pattern_2 = re.compile(r'include \'(.*)\'')
122
	includes = include_directive_pattern_1.findall(asm_file_contents)
123
	includes += include_directive_pattern_2.findall(asm_file_contents)
124
	for include in includes:
125
		include = include.replace('\\', '/');
126
		full_path = subdir + '/' + include;
127
		if full_path not in handled_files:
128
			new_subdir = full_path.rsplit('/', 1)[0]
129
			get_includes(handled_files, full_path, new_subdir)
130
	return handled_files
131
 
132
kernel_files = []
133
 
134
get_includes(kernel_files, "./kernel.asm");
135
 
136
for source in kernel_structure:
137
	print(f"File: {source}")
138
	if len(kernel_structure[source][VARIABLES]) > 0:
139
		print(" Variables:")
140
		for variable in kernel_structure[source][VARIABLES]:
141
			print(f"  {variable[0]}: {variable[1]}")
142
	if len(kernel_structure[source][PROCEDURES]) > 0:
143
		print(" Procedures:")
144
		for procedure in kernel_structure[source][PROCEDURES]:
145
			print(f"  {procedure[0]}: {procedure[1]}")
146
	if len(kernel_structure[source][LABELS]) > 0:
147
		print(" Global labels:")
148
		for label in kernel_structure[source][LABELS]:
149
			print(f"  {label[0]}: {label[1]}")
150
	if len(kernel_structure[source][MACROS]) > 0:
151
		print(" Macroses:")
152
		for macro in kernel_structure[source][MACROS]:
153
			print(f"  {macro[0]}: {macro[1]}")
154
	if len(kernel_structure[source][STRUCTURES]) > 0:
155
		print(" Structures:")
156
		for struct in kernel_structure[source][STRUCTURES]:
157
			print(f"  {struct[0]}: {struct[1]}")
158
 
159
# Collect stats
160
var_count = 0
161
proc_count = 0
162
label_count = 0
163
macro_count = 0
164
struct_count = 0
165
 
166
for source in kernel_structure:
167
	var_count += len(kernel_structure[source][VARIABLES])
168
	proc_count += len(kernel_structure[source][PROCEDURES])
169
	label_count += len(kernel_structure[source][LABELS])
170
	macro_count += len(kernel_structure[source][MACROS])
171
	struct_count += len(kernel_structure[source][STRUCTURES])
172
 
173
print(f"Variable count: {var_count}")
174
print(f"Procedures count: {proc_count}")
175
print(f"Global labels count: {label_count}")
176
print(f"Macroses count: {macro_count}")
177
print(f"Structures count: {struct_count}")
178
 
179
#for kernel_file in kernel_files:
180
#	print(kernel_file)