0,0 → 1,180 |
import os |
from glob import glob |
|
""" |
# Collect all .inc files |
kernel_files = [y for x in os.walk(".") for y in glob(os.path.join(x[0], '*.inc'))] |
|
to_remove = [] |
for i in range(len(kernel_files)): |
inc = kernel_files[i] |
# Remove files that aren't a part of the kernel |
if "bootloader" in inc or "sec_loader" in inc: |
to_remove.append(i) |
|
for i in range(len(to_remove) - 1, -1, -1): |
kernel_files.pop(to_remove[i]) |
|
# Add main kernel file |
kernel_files.append("kernel.asm") |
|
# Add main kernel file |
# TODO: Rename the file so it won't be an exception |
kernel_files.append("fs/xfs.asm") |
""" |
|
import re |
|
# kernel_structure["filename"] = { |
# [ [], # [0] Variables - [ line, name ] |
# [], # [1] Macros - [ line, name ] |
# [], # [2] Procedures - [ line, name ] |
# [], # [3] Labels - [ line, name ] |
# [] ] } # [4] Structures - [ line, name ] |
VARIABLES = 0 |
MACROS = 1 |
PROCEDURES = 2 |
LABELS = 3 |
STRUCTURES = 4 |
kernel_structure = {} |
|
def get_declarations(asm_file_contents, asm_file_name): |
kernel_structure[asm_file_name] = [ [], [], [], [], [] ] |
|
variable_pattern = re.compile(r'^\s*([\w\.]+)\s+d[bwdq] .*') |
macro_pattern = re.compile(r'^\s*macro\s+([\w]+).*') |
proc_pattern = re.compile(r'^\s*proc\s+([\w\.]+).*') |
label_pattern = re.compile(r'^(?!;)\s*([\w\.]+):.*') |
struct_pattern = re.compile(r'^\s*struct\s+([\w]+).*') |
|
line_idx = 0 |
lines = asm_file_contents.splitlines() |
while line_idx < len(lines): |
line = lines[line_idx] |
|
match = variable_pattern.findall(line) |
if len(match) > 0: |
var_name = match[0] |
#print(f"Variable '{var_name}' at {line_idx + 1}") |
kernel_structure[asm_file_name][VARIABLES].append([ line_idx + 1, var_name ]) |
line_idx += 1 |
continue |
|
match = macro_pattern.findall(line) |
if len(match) > 0: |
macro_name = match[0] |
#print(f"Macro '{macro_name}' at {line_idx + 1}") |
kernel_structure[asm_file_name][MACROS].append([ line_idx + 1, macro_name ]) |
end_of_macro = False |
while not end_of_macro: |
line = lines[line_idx] |
rbraces = re.finditer('}', line) |
for rbrace_match in rbraces: |
rbrace_idx = rbrace_match.start() |
if line[rbrace_idx - 1] != '\\': |
end_of_macro = True |
line_idx += 1 |
continue |
|
match = proc_pattern.findall(line) |
if len(match) > 0: |
proc_name = match[0] |
#print(f"Procedure '{proc_name}' at {line_idx + 1}") |
kernel_structure[asm_file_name][PROCEDURES].append([ line_idx + 1, proc_name ]) |
line_idx += 1 |
continue |
|
match = label_pattern.findall(line) |
if len(match) > 0: |
label_name = match[0] |
# Don't count local labels |
if label_name[0] != '.': |
#print(f"Label '{label_name}' at {line_idx + 1}") |
kernel_structure[asm_file_name][LABELS].append([ line_idx + 1, label_name ]) |
line_idx += 1 |
continue |
|
match = struct_pattern.findall(line) |
if len(match) > 0: |
struct_name = match[0] |
#print(f"Structure '{struct_name}' at {line_idx + 1}") |
kernel_structure[asm_file_name][STRUCTURES].append([ line_idx + 1, struct_name ]) |
end_of_struct = False |
while not end_of_struct: |
line = lines[line_idx] |
if re.match(r"^ends$", line) != None: |
end_of_struct = True |
line_idx += 1 |
continue |
|
line_idx += 1 |
|
def get_includes(handled_files, asm_file_name, subdir = "."): |
print(f"Handling {asm_file_name}") |
handled_files.append(asm_file_name) |
try: |
asm_file_contents = open(asm_file_name, "r", encoding="utf-8").read() |
except: |
return |
get_declarations(asm_file_contents, asm_file_name) |
include_directive_pattern_1 = re.compile(r'include "(.*)"') |
include_directive_pattern_2 = re.compile(r'include \'(.*)\'') |
includes = include_directive_pattern_1.findall(asm_file_contents) |
includes += include_directive_pattern_2.findall(asm_file_contents) |
for include in includes: |
include = include.replace('\\', '/'); |
full_path = subdir + '/' + include; |
if full_path not in handled_files: |
new_subdir = full_path.rsplit('/', 1)[0] |
get_includes(handled_files, full_path, new_subdir) |
return handled_files |
|
kernel_files = [] |
|
get_includes(kernel_files, "./kernel.asm"); |
|
for source in kernel_structure: |
print(f"File: {source}") |
if len(kernel_structure[source][VARIABLES]) > 0: |
print(" Variables:") |
for variable in kernel_structure[source][VARIABLES]: |
print(f" {variable[0]}: {variable[1]}") |
if len(kernel_structure[source][PROCEDURES]) > 0: |
print(" Procedures:") |
for procedure in kernel_structure[source][PROCEDURES]: |
print(f" {procedure[0]}: {procedure[1]}") |
if len(kernel_structure[source][LABELS]) > 0: |
print(" Global labels:") |
for label in kernel_structure[source][LABELS]: |
print(f" {label[0]}: {label[1]}") |
if len(kernel_structure[source][MACROS]) > 0: |
print(" Macroses:") |
for macro in kernel_structure[source][MACROS]: |
print(f" {macro[0]}: {macro[1]}") |
if len(kernel_structure[source][STRUCTURES]) > 0: |
print(" Structures:") |
for struct in kernel_structure[source][STRUCTURES]: |
print(f" {struct[0]}: {struct[1]}") |
|
# Collect stats |
var_count = 0 |
proc_count = 0 |
label_count = 0 |
macro_count = 0 |
struct_count = 0 |
|
for source in kernel_structure: |
var_count += len(kernel_structure[source][VARIABLES]) |
proc_count += len(kernel_structure[source][PROCEDURES]) |
label_count += len(kernel_structure[source][LABELS]) |
macro_count += len(kernel_structure[source][MACROS]) |
struct_count += len(kernel_structure[source][STRUCTURES]) |
|
print(f"Variable count: {var_count}") |
print(f"Procedures count: {proc_count}") |
print(f"Global labels count: {label_count}") |
print(f"Macroses count: {macro_count}") |
print(f"Structures count: {struct_count}") |
|
#for kernel_file in kernel_files: |
# print(kernel_file) |