172 lines
7.7 KiB
Matlab
172 lines
7.7 KiB
Matlab
classdef editCode
|
||
|
||
methods(Static)
|
||
|
||
function newCode = insertSection(code, sectionName, newText)
|
||
% insertSection – вставка или замена содержимого секции или тела функции
|
||
% Аргументы:
|
||
% code – исходный текст (строка)
|
||
% sectionName – имя секции (например, 'MY_SECTION') или заголовок функции (например, 'void myFunc(...)')
|
||
% newText – новый текст, который будет вставлен внутрь секции или функции
|
||
%
|
||
% Возвращает:
|
||
% newCode – обновлённый текст с подставленным содержимым
|
||
%
|
||
% Особенности:
|
||
% - Если sectionName начинается с 'void ', считается что это функция, и вставка происходит внутрь её тела.
|
||
% - В остальных случаях ищется секция между маркерами "<NAME> START" и "<NAME> END", и она заменяется на newText.
|
||
|
||
newCode = code;
|
||
|
||
% Если это функция
|
||
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)
|
||
% extractSection – извлечение содержимого секции или тела функции
|
||
% Аргументы:
|
||
% code – исходный текст (строка)
|
||
% sectionName – имя секции (например, 'MY_SECTION') или заголовок функции (например, 'void myFunc(...)')
|
||
%
|
||
% Возвращает:
|
||
% result – извлечённый текст из секции или тела функции
|
||
%
|
||
% Особенности:
|
||
% - Если sectionName начинается с 'void ', считается что это функция, и извлекается содержимое её тела.
|
||
% - В остальных случаях ищется секция между маркерами "<NAME> START" и "<NAME> END".
|
||
|
||
result = '';
|
||
% Если это функция (начинается с '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
|
||
|
||
% Найдём \n после {
|
||
newlineAfterOpen = regexp(code(braceOpenIdx:end), '\n', 'once');
|
||
if isempty(newlineAfterOpen)
|
||
return;
|
||
end
|
||
bodyStart = braceOpenIdx + newlineAfterOpen;
|
||
|
||
% Найдём \n до }
|
||
newlinesBeforeClose = regexp(code(1:braceCloseIdx), '\n');
|
||
if isempty(newlinesBeforeClose)
|
||
return;
|
||
end
|
||
bodyEnd = newlinesBeforeClose(end) - 1;
|
||
|
||
% Извлекаем блок как есть, включая отступы
|
||
result = code(bodyStart:bodyEnd);
|
||
return;
|
||
end
|
||
|
||
% Иначе считаем, что это секция вида // NAME START ... // NAME 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 |