Subversion Repositories Kolibri OS

Rev

Rev 8834 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  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)
  181.