release 1.0

This commit is contained in:
2025-06-14 19:51:05 +03:00
commit 1bd5009b9d
25 changed files with 3386 additions and 0 deletions

172
McuLib/m/editCode.m Normal file
View File

@@ -0,0 +1,172 @@
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