debugVarTool/Src/parseMakefile.py
Razvalyaev 4962276760 работа с таблицей перенесена в отдельный файл
сделано автозаполнение при поиске переменых
сделано правильное формирование структур, через . или ->

пофиксены мелкие фиксы
2025-07-09 15:40:16 +03:00

155 lines
5.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import os
import re
def strip_single_line_comments(code):
# Удалим // ... до конца строки
return re.sub(r'//.*?$', '', code, flags=re.MULTILINE)
def read_file_try_encodings(filepath):
if not os.path.isfile(filepath):
# Файл не существует — просто вернуть пустую строку или None
return "", None
for enc in ['utf-8', 'cp1251']:
try:
with open(filepath, 'r', encoding=enc) as f:
content = f.read()
content = strip_single_line_comments(content)
return content, enc
except UnicodeDecodeError:
continue
raise UnicodeDecodeError(f"Не удалось прочитать файл {filepath} с кодировками utf-8 и cp1251")
def find_all_includes_recursive(c_files, include_dirs, processed_files=None):
"""
Рекурсивно ищет все include-файлы начиная с заданных c_files.
Возвращает множество ПОЛНЫХ ПУТЕЙ к найденным include-файлам.
include_dirs — список директорий, в которых ищем include-файлы.
processed_files — множество уже обработанных файлов (для избежания циклов).
"""
if processed_files is None:
processed_files = set()
include_files = set()
include_pattern = re.compile(r'#include\s+"([^"]+)"')
for cfile in c_files:
norm_path = os.path.normpath(cfile)
if norm_path in processed_files:
continue
processed_files.add(norm_path)
content, _ = read_file_try_encodings(cfile)
if content is None:
continue
includes = include_pattern.findall(content)
for inc in includes:
# Ищем полный путь к include-файлу в include_dirs
inc_full_path = None
for dir_ in include_dirs:
candidate = os.path.normpath(os.path.join(dir_, inc))
if os.path.isfile(candidate):
inc_full_path = os.path.abspath(candidate)
break
if inc_full_path:
include_files.add(inc_full_path)
# Рекурсивный обход вложенных includes
if inc_full_path not in processed_files:
nested_includes = find_all_includes_recursive(
[inc_full_path], include_dirs, processed_files
)
include_files.update(nested_includes)
return include_files
def parse_makefile(makefile_path, proj_path):
makefile_dir = os.path.dirname(makefile_path)
project_root = proj_path
with open(makefile_path, 'r', encoding='utf-8') as f:
lines = f.readlines()
objs_lines = []
collecting = False
for line in lines:
stripped = line.strip()
if stripped.startswith("ORDERED_OBJS") and "+=" in stripped:
parts = stripped.split("\\")
first_part = parts[0]
idx = first_part.find("+=")
tail = first_part[idx+2:].strip()
if tail:
objs_lines.append(tail)
collecting = True
if len(parts) > 1:
for p in parts[1:]:
p = p.strip()
if p:
objs_lines.append(p)
continue
if collecting:
if stripped.endswith("\\"):
objs_lines.append(stripped[:-1].strip())
else:
objs_lines.append(stripped)
collecting = False
objs_str = ' '.join(objs_lines)
objs_str = re.sub(r"\$\([^)]+\)", "", objs_str)
objs = []
for part in objs_str.split():
part = part.strip()
if part.startswith('"') and part.endswith('"'):
part = part[1:-1]
if part:
objs.append(part)
c_files = []
include_dirs = set()
for obj_path in objs:
if "DebugTools" in obj_path:
continue
if "v120" in obj_path:
continue
if "v100" in obj_path:
continue
if obj_path.startswith("Debug\\") or obj_path.startswith("Debug/"):
rel_path = obj_path.replace("Debug\\", "Src\\").replace("Debug/", "Src/")
else:
rel_path = obj_path
abs_path = os.path.normpath(os.path.join(project_root, rel_path))
root, ext = os.path.splitext(abs_path)
if ext.lower() == ".obj":
c_path = root + ".c"
else:
c_path = abs_path
# Проверяем существование файла, если нет — пропускаем
if not os.path.isfile(c_path):
continue
# Сохраняем только .c файлы
if c_path.lower().endswith(".c"):
c_files.append(c_path)
dir_path = os.path.dirname(c_path)
if dir_path and "DebugTools" not in dir_path:
include_dirs.add(dir_path)
h_files = find_all_includes_recursive(c_files, include_dirs)
return sorted(c_files), sorted(h_files), sorted(include_dirs)