3 [fileList,reportList]=scan(dirNameList,...
5 [htmlOut,fullFileNameList,reportList]=...
6 scanWithHtmlReport(dirList,patternToExclude)
9 function [fileList,reportList]=scan(dirNameList,pathPatternToExclude)
10 pathList=
mxberry.io.PathUtils.genPathByRootList(dirNameList,...
11 pathPatternToExclude);
13 [reportListOfList,fileListOfList]=cellfun(@(x)scanDir(x),pathList,...
14 'UniformOutput',false);
15 isnEmptyVec=~cellfun('isempty',reportListOfList);
16 fileListOfList=fileListOfList(isnEmptyVec);
17 reportListOfList=reportListOfList(isnEmptyVec);
18 fileList=vertcat(fileListOfList{:});
19 reportList=vertcat(reportListOfList{:});
26 function [reportList,localFilenames]=scanDir(dirName)
27 dirFileList = what(dirName);
28 fileList = sort([dirFileList.m]);
29 localFilenames = strcat(dirName,
filesep,fileList);
30 reportList=mlint(localFilenames,
'-struct');
32 isnEmptyVec=~cellfun(
'isempty',reportList);
33 reportList=reportList(isnEmptyVec);
34 localFilenames=localFilenames(isnEmptyVec);
36 function [htmlOut,fullFileNameList,reportList]=scanWithHtmlReport(dirList,patternToExclude)
37 [fullFileNameList,reportList]=...
40 [~,fileList]=cellfun(@fileparts,fullFileNameList,
'UniformOutput',
false);
42 SHtmlProxyReportVec = [];
43 reportName =
'MLint-MXBerry Code Analyzer Report';
45 nFiles=numel(fullFileNameList);
48 SHtmlProxyReportVec(iFile).fileName = fileList{iFile}; %#ok<*AGROW>
49 SHtmlProxyReportVec(iFile).fullFileName = fullFileNameList{iFile};
51 SHtmlProxyReportVec(iFile).lineNumber = [];
52 SHtmlProxyReportVec(iFile).lineMessage = {};
54 SMlintProblemVec = reportList{iFile};
55 for iProblem = 1:numel(SMlintProblemVec)
56 ln = SMlintProblemVec(iProblem).message;
58 for iLine = 1:numel(SMlintProblemVec(iProblem).line)
59 SHtmlProxyReportVec(iFile).lineNumber(end+1) = ...
60 SMlintProblemVec(iProblem).line(iLine);
61 SHtmlProxyReportVec(iFile).lineMessage{end+1} = ln;
65 % Now sort the list by line number
66 if ~isempty(SHtmlProxyReportVec(iFile).lineNumber)
67 lineNum = [SHtmlProxyReportVec(iFile).lineNumber];
68 lineMsg = SHtmlProxyReportVec(iFile).lineMessage;
69 [~, ndx] = sort(lineNum);
70 lineNum = lineNum(ndx);
71 lineMsg = lineMsg(ndx);
72 SHtmlProxyReportVec(iFile).lineNumber = lineNum;
73 SHtmlProxyReportVec(iFile).lineMessage = lineMsg;
78 % Limit the number of messages displayed to keep from being overwhelmed by
79 % large pathological files.
82 % Now generate the HTML
84 rerunAction = sprintf(...
85 'mxberry.dev.MLintScanner.scanWithHtmlReport(%s,''%s'')',...
86 dirListExpr,patternToExclude);
87 s = makeReportHeader(reportName, rerunAction);
89 s{end+1} =
'<table cellspacing="0" cellpadding="2" border="0">';
90 for n = 1:length(SHtmlProxyReportVec)
91 encodedFileName = urlencode(SHtmlProxyReportVec(n).fullFileName);
92 decodedFileName = urldecode(encodedFileName);
94 s{end+1} =
'<tr><td valign="top" class="td-linetop">';
95 openInEditor = sprintf(
'edit(''%s'')',decodedFileName);
96 regExpRep = sprintf(
'%s', SHtmlProxyReportVec(n).fileName);
98 s{end+1} = [
'<a href="matlab:' openInEditor
'">'];
99 s{end+1} = sprintf(
'<span class="mono">');
100 s{end+1} = regExpRep;
101 s{end+1} = sprintf(
'</span> </a> </br>');
103 if isempty(SHtmlProxyReportVec(n).lineNumber)
104 msgStr =
'<span class="soft"> No Messages </span>';
105 elseif length(SHtmlProxyReportVec(n).lineNumber)==1
106 msgStr =
'<span class="warning"> 1 message </span>';
107 elseif length(SHtmlProxyReportVec(n).lineNumber) < DISPLAY_LIMIT
108 msgStr = [
'<span class="warning">',...
109 sprintf(
'%d messages',length(SHtmlProxyReportVec(n).lineNumber)),...
112 % Truncate the list of messages
if there are too many.
113 msgStr = [
'<span class="warning">',...
114 sprintf(
'%d messages',length(SHtmlProxyReportVec(n).lineNumber)), ...
116 sprintf(
'Showing only first %d',DISPLAY_LIMIT),
'</span>'];
118 s{end+1} = sprintf(
'%s</td><td valign="top" class="td-linetopleft">',msgStr);
120 if ~isempty(SHtmlProxyReportVec(n).lineNumber)
121 for m = 1:min(length(SHtmlProxyReportVec(n).lineNumber),DISPLAY_LIMIT)
123 openMessageLine = sprintf(
'opentoline(''%s'',%d)',...
124 decodedFileName, SHtmlProxyReportVec(n).lineNumber(m));
126 lineNum = sprintf(
'%d', SHtmlProxyReportVec(n).lineNumber(m));
127 lineMsg = sprintf(
'%s',SHtmlProxyReportVec(n).lineMessage{m});
129 s{end+1} = sprintf(
'<span class="mono">');
130 s{end+1} = [
'<a href="matlab:' openMessageLine
'">'];
132 s{end+1} = sprintf(
'</a> ');
134 s{end+1} = sprintf(
'</span> <br/>');
137 s{end+1} =
'</td></tr>';
140 s{end+1} =
'</table>';
141 s{end+1} =
'</body></html>';
145 web([
'text://' sOut],
'-noaddressbox');
150 function htmlOut = makeReportHeader( reportName,rerunAction)
154 h1 =
'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">';
155 h2 =
'<html xmlns="http://www.w3.org/1999/xhtml">';
157 h3 = sprintf(
'<head><meta http-equiv="Content-Type" content="text/html; charset=%s" />',encoding);
158 %% Add cascading style sheet link
159 reportdir = fullfile(matlabroot,
'toolbox',
'matlab',
'codetools',
'+internal',
'+matlab',
'+codetools',
'+reports');
160 cssfile = fullfile(reportdir,
'matlab-report-styles.css');
161 h4 = sprintf(
'<link rel="stylesheet" href="file:///%s" type="text/css" />', cssfile);
163 jsfile = fullfile(reportdir,
'matlabreports.js');
164 h5 = sprintf(
'<script type="text/javascript" language="JavaScript" src="file:///%s"></script>',jsfile);
167 htmlOut{1} = [h1 h2 h3 h4 h5];
169 htmlOut{2} = sprintf(
'<title>%s</title>', reportName);
170 htmlOut{3} =
'</head>';
171 htmlOut{4} =
'<body>';
172 htmlOut{5} = sprintf(
'<div class="report-head">%s</div><p>', reportName);
176 htmlOut{end+1} =
'<table border="0"><tr>';
177 htmlOut{end+1} =
'<td>';
178 htmlOut{end+1} = sprintf(
'<input type="button" value="%s" id="rerunThisReport" onclick="runreport(''%s'');" />',...
179 'Rerun This Report', escape(rerunAction));
180 htmlOut{end+1} =
'</td>';
182 function escapedAction = escape(action)
183 escapedAction = regexprep(action,
'[\\'']',
'\\$0');
184 char(com.mathworks.mlwidgets.html.HTMLUtils.encodeUrl(escapedAction));
function scan(in dirNameList, in pathPatternToExclude)