Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I make custom matlab code-analyser warnings?

The matlab code-analyzer has a lot of nice suggestions on how to correct errors and inefficiencies, but I sometimes encounter situations that I would like to be caught by the analyzer. Specifically I am thinking of code like the following:

if numel(list > x)
  ...
end

I can't off the top of my head think of any situation where I need to use the above code whereas the following code:

if numel(list) > x
  ...
end

is quite often used.

I looked through the list of possible things the code-analyzer could warn me about and I did not find this possibility.

So my question is: Is it possible to add my own warnings to the code-analyzer, and if so, how?

I realize that if it possible it might be a difficult task, so any alternatives or workaround suggestions for the specific problem would also be appreciated!

like image 711
Jens Boldsen Avatar asked Dec 20 '16 12:12

Jens Boldsen


1 Answers

I don't believe there's a way to add new code patterns for the MATLAB Code Analyzer to look for. All you can do is set which existing warnings are displayed or suppressed.

I'm not sure what sort of third-party tools there might be for code analysis, and creating a general purpose analyzer yourself would be quite daunting. However, if there were a few very specific, well-defined patterns you wanted to try and highlight in your code, you could attempt parsing it with regular expressions (cue scary music and screaming).

This can often be difficult, but doable. As an example, I wrote up this piece of code that looks for the pattern you mention above. One of the things that often has to be managed when doing something like this is accounting for sets of enclosing parentheses, which I handle by first removing non-interesting pairs of parentheses and their contents:

function check_code(filePath)

  % Read lines from the file:
  fid = fopen(filePath, 'r');
  codeLines = textscan(fid, '%s', 'Delimiter', '\n');
  fclose(fid);
  codeLines = codeLines{1};

  % Remove sets of parentheses that do not encapsulate a logical statement:
  tempCode = codeLines;
  modCode = regexprep(tempCode, '\([^\(\)<>=~\|\&]*\)', '');
  while ~isequal(modCode, tempCode)
    tempCode = modCode;
    modCode = regexprep(tempCode, '\([^\(\)<>=~\|\&]*\)', '');
  end

  % Match patterns using regexp:
  matchIndex = regexp(modCode, 'numel\([^\(\)]+[<>=~\|\&]+[^\(\)]+\)');

  % Format return information:
  nMatches = cellfun(@numel, matchIndex);
  index = find(nMatches);
  lineNumbers = repelem(index, nMatches(index));
  fprintf('Line %d: Potential incorrect use of NUMEL in logical statement.\n', ...
          lineNumbers);

end
% Test cases:
%   if numel(list < x)
%   if numel(list) < x
%   if numel(list(:,1)) < x
%   if numel(list(:,1) < x)
%   if (numel(list(:,1)) < x)
%   if numel(list < x) & numel(list < y)
%   if (numel(list) < x) & (numel(list) < y)

Notice I added some test cases in the comments at the bottom of the file. When I run this code on itself, I get this:

>> check_code('check_code.m')
Line 28: Potential incorrect use of NUMEL in logical statement.
Line 31: Potential incorrect use of NUMEL in logical statement.
Line 33: Potential incorrect use of NUMEL in logical statement.
Line 33: Potential incorrect use of NUMEL in logical statement.

Notice that a message is listed for the first, fourth, and sixth test cases that match your erroneous code (twice for the sixth test case, since there are two errors on that line).

Will this work for all possible situations? I would assume not. You'll likely have to increase the complexity of the regex patterns to handle additional situations. But at least this may serve as an example of the sort of things you have to consider when parsing code.

like image 83
gnovice Avatar answered Oct 31 '22 07:10

gnovice