Все изменения накопившиеся с релиза

This commit is contained in:
2025-11-14 21:56:39 +03:00
parent ac2fe4d653
commit 9b8b5ec533
17 changed files with 1008 additions and 699 deletions

View File

@@ -1,60 +1,71 @@
classdef editCode
% Класс для редактирования кода C/C++ в текстовых файлах
% Обеспечивает извлечение и вставку кода в секции и функции
methods(Static)
function newCode = insertSection(code, sectionName, newText)
% insertSection вставка или замена содержимого секции или тела функции
% Вставка или замена содержимого секции или тела функции
%
% Аргументы:
% code исходный текст (строка)
% sectionName имя секции (например, 'MY_SECTION') или заголовок функции (например, 'void myFunc(...)')
% newText новый текст, который будет вставлен внутрь секции или функции
% code - исходный текст кода как строка
% sectionName - имя секции (например, 'MY_SECTION') или
% заголовок функции (например, 'void myFunc(...)')
% newText - новый текст для вставки внутрь секции или функции
%
% Возвращает:
% newCode обновлённый текст с подставленным содержимым
% newCode - обновлённый текст с подставленным содержимым
%
% Особенности:
% - Если sectionName начинается с 'void ', считается что это функция, и вставка происходит внутрь её тела.
% - В остальных случаях ищется секция между маркерами "<NAME> START" и "<NAME> END", и она заменяется на newText.
% - Если sectionName начинается с 'void ', считается что это функция,
% и вставка происходит внутрь её тела
% - Для секций ищется блок между маркерами "NAME START" и "NAME END"
% - Поддерживает функции с параметрами и вложенными скобками
newCode = code;
% Если это функция
% Обработка функций (если sectionName начинается с 'void ')
if startsWith(strtrim(sectionName), 'void ')
% Извлекаем имя функции из заголовка
tokens = regexp(sectionName, 'void\s+(\w+)\s*\(', 'tokens');
if isempty(tokens)
return;
return; % Не удалось извлечь имя функции
end
funcName = tokens{1}{1};
% Ищем начало функции в коде
expr = sprintf('void\\s+%s\\s*\\(.*?\\)\\s*\\{', funcName);
startIdx = regexp(code, expr, 'start');
if isempty(startIdx)
return;
return; % Функция не найдена
end
% Найдём тело функции с учётом вложенных скобок
% Находим тело функции с учётом вложенных фигурных скобок
from = startIdx(1);
braceCount = 0;
braceCount = 0; % Счётчик уровня вложенности скобок
i = from;
while i <= length(code)
if code(i) == '{'
braceCount = braceCount + 1;
if braceCount == 1
bodyStart = i + 1;
bodyStart = i + 1; % Начало тела функции (после {)
end
elseif code(i) == '}'
braceCount = braceCount - 1;
if braceCount == 0
bodyEnd = i - 1;
bodyEnd = i - 1; % Конец тела функции (перед })
break;
end
end
i = i + 1;
end
% Проверяем что все скобки закрыты
if braceCount ~= 0
return;
return; % Несбалансированные скобки
end
% Собираем новый код: начало до тела + новый текст + конец после тела
newCode = [ ...
code(1:bodyStart-1), ...
newline, newText, newline, ...
@@ -63,111 +74,113 @@ classdef editCode
return;
end
% Иначе это обычная секция
% Формируем шаблон с группами для поиска нужного блока
% Обработка обычных секций (не функций)
% Формируем шаблон для поиска секции: начало, содержимое, конец
pattern = sprintf('(%s START\\s*\\n)(.*?)(\\s*%s END)', sectionName, sectionName);
% Проверяем, есть ли совпадение
% Проверяем наличие секции в коде
startIdx = regexp(code, pattern, 'start', 'once');
if isempty(startIdx)
error('Секция "%s" не найдена в тексте.', sectionName);
end
% Формируем новую секцию с нужным текстом
% newText = strrep(newText, '\', '\\'); % экранируем для корректной вставки
% Формируем новую секцию с переданным текстом
replacement = sprintf('%s START\n%s\n%s END', sectionName, newText, sectionName);
% Заменяем всю найденную секцию на новую
newCode = regexprep(code, pattern, replacement, 'dotall');
end
function result = extractSection(code, sectionName)
% extractSection извлечение содержимого секции или тела функции
% Извлечение содержимого секции или тела функции
%
% Аргументы:
% code исходный текст (строка)
% sectionName имя секции (например, 'MY_SECTION') или заголовок функции (например, 'void myFunc(...)')
% code - исходный текст кода как строка
% sectionName - имя секции (например, 'MY_SECTION') или
% заголовок функции (например, 'void myFunc(...)')
%
% Возвращает:
% result извлечённый текст из секции или тела функции
% result - извлечённый текст из секции или тела функции
%
% Особенности:
% - Если sectionName начинается с 'void ', считается что это функция, и извлекается содержимое её тела.
% - В остальных случаях ищется секция между маркерами "<NAME> START" и "<NAME> END".
% - Для функций извлекает содержимое между { и } с учётом вложенности
% - Для секций извлекает текст между маркерами START и END
% - Сохращает оригинальные отступы и форматирование
result = '';
% Если это функция (начинается с 'void ')
% Обработка функций (если sectionName начинается с 'void ')
if startsWith(strtrim(sectionName), 'void ')
% Получаем имя функции из заголовка
% Извлекаем имя функции из заголовка
tokens = regexp(sectionName, 'void\s+(\w+)\s*\(', 'tokens');
if isempty(tokens)
return;
return; % Не удалось извлечь имя функции
end
funcName = tokens{1}{1};
% Строим шаблон начала функции
% Ищем начало функции в коде
expr = sprintf('void\\s+%s\\s*\\(.*?\\)\\s*\\{', funcName);
startIdx = regexp(code, expr, 'start');
if isempty(startIdx)
return;
return; % Функция не найдена
end
% Поиск тела функции с учётом вложенных скобок
% Находим тело функции с учётом вложенных фигурных скобок
from = startIdx(1);
braceCount = 0;
braceCount = 0; % Счётчик уровня вложенности скобок
i = from;
while i <= length(code)
if code(i) == '{'
braceCount = braceCount + 1;
if braceCount == 1
% Найдём первую новую строку после {
braceOpenIdx = i;
braceOpenIdx = i; % Позиция открывающей скобки
end
elseif code(i) == '}'
braceCount = braceCount - 1;
if braceCount == 0
braceCloseIdx = i;
braceCloseIdx = i; % Позиция закрывающей скобки
break;
end
end
i = i + 1;
end
% Проверяем что все скобки закрыты
if braceCount ~= 0
return;
return; % Несбалансированные скобки
end
% Найдём \n после {
% Находим первую новую строку после открывающей скобки {
newlineAfterOpen = regexp(code(braceOpenIdx:end), '\n', 'once');
if isempty(newlineAfterOpen)
return;
return; % Не найден перевод строки
end
bodyStart = braceOpenIdx + newlineAfterOpen;
bodyStart = braceOpenIdx + newlineAfterOpen; % Начало тела функции
% Найдём \n до }
% Находим последнюю новую строку перед закрывающей скобкой }
newlinesBeforeClose = regexp(code(1:braceCloseIdx), '\n');
if isempty(newlinesBeforeClose)
return;
return; % Не найдены переводы строк
end
bodyEnd = newlinesBeforeClose(end) - 1;
bodyEnd = newlinesBeforeClose(end) - 1; % Конец тела функции
% Извлекаем блок как есть, включая отступы
% Извлекаем тело функции с сохранением форматирования
result = code(bodyStart:bodyEnd);
return;
end
% Иначе считаем, что это секция вида // NAME START ... // NAME END
% Обработка обычных секций (не функций)
% Ищем секцию между маркерами START и END
pattern = sprintf('%s START\\s*\\n(.*?)\n%s END', sectionName, sectionName);
% Извлекаем содержимое секции
match = regexp(code, pattern, 'tokens', 'dotall');
if ~isempty(match)
result = match{1}{1};
result = match{1}{1}; % Возвращаем содержимое секции
else
% Секция не найдена - выводим сообщение об ошибке
mcuMask.disp(0, 'Ошибка: cекция "%s" не найдена в тексте.', sectionName);
end
end
end
end