2016-03-09 2 views
5

Я использую код в MATLAB, чтобы предоставить мне структуру всех сообщений об ошибках в прилагаемом имени файла вместе с их сложностью и идентификатором McCabe, связанными с этой ошибкой. то есть;Найти категорию MATLAB mlint warning ID

info = checkcode(fileName, '-cyc','-id'); 

В настройках MATLAB, есть список всех возможных ошибок, и они разбиты на категории. Такие как «Эстетика и читаемость», «Ошибки синтаксиса», «Отклонение от использования функций» и т. Д.

Есть ли способ доступа к этим категориям с использованием идентификатора ошибки, полученного из указанной выше строки кода?

+0

Можете ли вы связать некоторую документацию, где объясняются категории thoe? Я не могу найти его .... –

+0

На вкладке «Главная» нажмите «Настройки» в разделе «Окружающая среда», затем выберите «Анализатор кода» слева. Все категории находятся там. –

+1

Чтобы уточнить, я намерен ввести идентификатор ошибки, такой как «DWVRD» (который соответствует ошибке «wavread будет удалён в будущей версии, используйте вместо него аудиозапись») в какую-то функцию, которая вернет категорию, в которой указан этот код ошибки перечисленные ниже и любые другие связанные с ним свойства. –

ответ

7

Я бросил вокруг меня разные идеи в этом вопросе и, наконец, смог придумать в основном элегантное решение, как справиться с этим.

Решение

Критический компонент этого решения является undocumented -allmsg флаг of checkcode (or mlint). Если вы укажете этот аргумент, будет напечатан полный список идентификаторов mlint, кодов серьезности и описаний. Что еще более важно, категории также, напечатанные в этом списке, и все mlint Идентификаторы перечислены под их соответствующей категорией mlint.

Исполнение

Теперь мы не можем просто вызвать checkcode (или mlint) с только-allmsg флаг, потому что это было бы слишком легко. Вместо этого для этого требуется фактический файл, чтобы попытаться проанализировать и проверить наличие ошибок. Вы можете получить , но я решил передать встроенный sum.m, потому что сам фактический файл содержит только справочную информацию (так как это реальная реализация, вероятно, C++), поэтому mlint поэтому может разобрать ее быстро без предупреждений.

checkcode('sum.m', '-allmsg'); 

Выдержка выхода печатного к окну команды:

INTER ========== Internal Message Fragments ========== 
    MSHHH 7 this is used for %#ok and should never be seen! 
    BAIL 7 done with run due to error 
    INTRN ========== Serious Internal Errors and Assertions ========== 
    NOLHS 3 Left side of an assignment is empty. 
    TMMSG 3 More than 50,000 Code Analyzer messages were generated, leading to some being deleted. 
    MXASET 4 Expression is too complex for code analysis to complete. 
    LIN2L 3 A source file line is too long for Code Analyzer. 
    QUIT 4 Earlier syntax errors confused Code Analyzer (or a possible Code Analyzer bug). 
    FILER ========== File Errors ========== 
    NOSPC 4 File <FILE> is too large or complex to analyze. 
    MBIG 4 File <FILE> is too big for Code Analyzer to handle. 
    NOFIL 4 File <FILE> cannot be opened for reading. 
    MDOTM 4 Filename <FILE> must be a valid MATLAB code file. 
    BDFIL 4 Filename <FILE> is not formed from a valid MATLAB identifier. 
    RDERR 4 Unable to read file <FILE>. 
    MCDIR 2 Class name <name> and @directory name do not agree: <FILE>. 
    MCFIL 2 Class name <name> and file name do not agree: <file>. 
    CFERR 1 Cannot open or read the Code Analyzer settings from file <FILE>. Using default settings instead. 
    ... 
    MCLL 1 MCC does not allow C++ files to be read directly using LOADLIBRARY. 
    MCWBF 1 MCC requires that the first argument of WEBFIGURE not come from FIGURE(n). 
    MCWFL 1 MCC requires that the first argument of WEBFIGURE not come from FIGURE(n) (line <line #>). 
    NITS ========== Aesthetics and Readability ========== 
    DSPS 1 DISP(SPRINTF(...)) can usually be replaced by FPRINTF(...). 
    SEPEX 0 For better readability, use newline, semicolon, or comma before this statement. 
    NBRAK 0 Use of brackets [] is unnecessary. Use parentheses to group, if needed. 
    ... 

Первый столбец явно mlint ID, второй столбец на самом деле Тяжесть числа (0 = основном безвредно, 1 = предупреждение, 2 = ошибка, 4-7 = более серьезные внутренние проблемы), а третий столбец - это сообщение, которое отображается.

Как вы можете видеть, все категории также имеют идентификатор, но не имеют серьезности, а их формат сообщения - ===== Category Name =====.

Итак, теперь мы можем просто проанализировать эту информацию и создать некоторую структуру данных, которая позволяет нам легко найти серьезность и категорию для заданного mlint ID.

Опять же, это не всегда может быть так просто. К сожалению, checkcode (или mlint) просто печатает эту информацию в окне команд и не присваивает ее ни одной из наших выходных переменных. Из-за этого необходимо использовать evalc (shudder), чтобы захватить вывод и сохранить его как строку. Затем мы можем легко проанализировать эту строку, чтобы получить категорию и степень серьезности, связанную с каждым mlint ID.

Пример Parser

Я поставил все части, которые я обсуждал ранее вместе в маленькую функцию, которая будет генерировать-структуру, где все поля являются идентификаторы mlint. В каждом поле вы получите следующую информацию:

warnings = mlintCatalog(); 
warnings.DWVRD 

      id: 'DWVRD' 
     severity: 2 
     message: 'WAVREAD has been removed. Use AUDIOREAD instead.' 
     category: 'Discouraged Function Usage' 
    category_id: 17 

И вот небольшая функция, если вам интересно.

function [warnings, categories] = mlintCatalog() 
    % Get a list of all categories, mlint IDs, and severity rankings 
    output = evalc('checkcode sum.m -allmsg'); 

    % Break each line into it's components 
    lines = regexp(output, '\n', 'split').'; 
    pattern = '^\s*(?<id>[^\s]*)\s*(?<severity>\d*)\s*(?<message>.*?\s*$)'; 
    warnings = regexp(lines, pattern, 'names'); 
    warnings = cat(1, warnings{:}); 

    % Determine which ones are category names 
    isCategory = cellfun(@isempty, {warnings.severity}); 
    categories = warnings(isCategory); 

    % Fix up the category names 
    pattern = '(^\s*=*\s*|\s*=*\s*$)'; 
    messages = {categories.message}; 
    categoryNames = cellfun(@(x)regexprep(x, pattern, ''), messages, 'uni', 0); 
    [categories.message] = categoryNames{:}; 

    % Now pair each mlint ID with it's category 
    comp = bsxfun(@gt, 1:numel(warnings), find(isCategory).'); 
    [category_id, ~] = find(diff(comp, [], 1) == -1); 
    category_id(end+1:numel(warnings)) = numel(categories); 

    % Assign a category field to each mlint ID 
    [warnings.category] = categoryNames{category_id}; 

    category_id = num2cell(category_id); 
    [warnings.category_id] = category_id{:}; 

    % Remove the categories from the warnings list 
    warnings = warnings(~isCategory); 

    % Convert warning severity to a number 
    severity = num2cell(str2double({warnings.severity})); 
    [warnings.severity] = severity{:}; 

    % Save just the categories 
    categories = rmfield(categories, 'severity'); 

    % Convert array of structs to a struct where the MLINT ID is the field 
    warnings = orderfields(cell2struct(num2cell(warnings), {warnings.id})); 
end 

Резюме

Это совершенно без документов, но достаточно надежный способ получения категории и тяжести, связанные с данным mlint ID. Эта функциональность существовала в 2010 году и, возможно, даже до этого, поэтому она должна работать с любой версией MATLAB, с которой вам приходится иметь дело. Этот подход также намного более гибкий, чем простое указание того, какие категории представляют собой идентификатор mlint, поскольку категория (и серьезность) будет изменяться с момента выпуска на выпуск при добавлении новых функций и устаревших старых функциях.

Благодарим за задание этого сложного вопроса, и я надеюсь, что этот ответ даст небольшую помощь и понимание!

+0

Это кажется гораздо лучшим решением, чем использование файла excel, который я создал для их хранения. Я обязательно буду обновлять свои методы. Спасибо. –

+0

+1 У меня было аналогичное предложение для linter-плагина для текстового редактора [Atom] (https://atom.io/): https://github.com/ajdm/linter-matlab/issues/2#issuecomment- 182097020 – Amro

0

Просто, чтобы закрыть эту проблему. Мне удалось извлечь данные из нескольких разных мест и собрать их вместе. Теперь у меня есть таблица Excel всех предупреждений и ошибок Matlab с столбцами для их соответствующих идентификационных кодов, категории и степени тяжести (т. Е. Если это предупреждение или ошибка). Теперь я могу прочитать этот файл, найти идентификационные коды, которые я получаю от использования функции «checkcode», и извлечь любую требуемую информацию. Теперь это можно использовать для создания инструментов анализа, чтобы посмотреть качество письменных скриптов/классов и т. Д.

Если кому-то захочется копировать этот файл, напишите мне сообщение, и я буду рад предоставить его.

Darren.

Смежные вопросы