mcu_matlab/McuLib/m/editCode.m
2025-11-07 14:52:52 +03:00

186 lines
9.8 KiB
Matlab
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.

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