улучшена таблица (растянута и форматирована) добавлен скрипт для компиляции .exe новые переменные можно добавлять в xml через .c напрямую (записываешь в .c он видит новую переменную и записывает в xml) можно удалять переменные из xml по del в окне выбора всех переменных надо подумать как реализовать выбор массивов и пофиксить баги: - кривая запись пути к файлу переменной в xml
144 lines
4.8 KiB
Python
144 lines
4.8 KiB
Python
import os
|
||
import re
|
||
|
||
|
||
def strip_single_line_comments(code):
|
||
# Удалим // ... до конца строки
|
||
return re.sub(r'//.*?$', '', code, flags=re.MULTILINE)
|
||
|
||
def read_file_try_encodings(filepath):
|
||
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)
|
||
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):
|
||
makefile_dir = os.path.dirname(makefile_path)
|
||
project_root = os.path.dirname(makefile_dir) # поднялись из Debug
|
||
|
||
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 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
|
||
|
||
# Сохраняем только .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)
|