mcu_matlab/McuLib/m/editCode.m
Razvalyaev df30570d4a мелкие парвки
- поддержка символа '\' вкладке Wrapper User Code
- исправлены дефайны OFFSET_IN/OUT_ARRAY
- убрана конфигурация портов во время подгрузки конфигурации периферии
- исправлены подписи таблицы (Alias почему-то не записывался)
2025-06-15 02:47:17 +03:00

173 lines
7.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
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
% Формируем новую секцию с нужным текстом
% 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(...)')
%
% Возвращает:
% 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