diff --git a/htmlreport/cppcheck-htmlreport b/htmlreport/cppcheck-htmlreport index 26eaa0cd7..57164b749 100755 --- a/htmlreport/cppcheck-htmlreport +++ b/htmlreport/cppcheck-htmlreport @@ -6,8 +6,9 @@ import io import sys import optparse import os -from collections import Counter +import operator +from collections import Counter from pygments import highlight from pygments.lexers import guess_lexer_for_filename from pygments.formatters import HtmlFormatter @@ -15,7 +16,6 @@ from xml.sax import parse as xml_parse from xml.sax import SAXParseException as XmlParseException from xml.sax.handler import ContentHandler as XmlContentHandler from xml.sax.saxutils import escape - """ Turns a cppcheck xml file into a browsable html report along with syntax highlighted source code. @@ -425,6 +425,7 @@ if __name__ == '__main__': # Generate a HTML file with syntax highlighted source code for each # file that contains one or more errors. print('Processing errors') + decode_errors = [] for filename, data in sorted(files.items()): htmlfile = data['htmlfile'] @@ -525,7 +526,7 @@ if __name__ == '__main__': stat_html.append(" " + str(dict(Counter(stats).most_common())[_id]) + " " + str(_id) + "
\n") output_file.write(HTML_HEAD.replace('id="menu" dir="rtl"', 'id="menu_index"', 1).replace("Defects:", "Defect summary;", 1) % (options.title, '', options.title, '', '')) - output_file.write('

\n' + ' ' + str(stats_count) + ' total

\n' + ''.join(stat_html) + '

') + output_file.write('

\n' + ' ' + str(stats_count) + ' total

\n' + ''.join(stat_html) + '

Statistics

') output_file.write(HTML_HEAD_END.replace("content", "content_index", 1)) output_file.write(' \n') output_file.write( @@ -583,4 +584,60 @@ if __name__ == '__main__': 'w') as css_file: css_file.write(STYLE_FILE) + + print("Creating stats.html (statistics)\n") + stats_countlist={} + + for filename, data in sorted(files.items()): + if (filename == ''): + continue + stats_tmplist=[] + for error in sorted(data['errors'], key=lambda k: k['line']): + stats_tmplist.append(error['severity']) + + stats_countlist[filename] = dict(Counter(stats_tmplist)) + + # get top ten for each severity + SEVERITIES = "error", "warning", "portability", "performance", "style", "unusedFunction", "information", "missingInclude", "internal" + + with io.open(os.path.join(options.report_dir, 'stats.html'), 'w') as stats_file: + + stats_file.write(HTML_HEAD.replace('id="menu" dir="rtl"', 'id="menu_index"', 1).replace("Defects:", "Back to summary", 1) % (options.title, '', options.title, 'Statistics', '')) + stats_file.write(HTML_HEAD_END.replace("content", "content_index", 1)) + + for sev in SEVERITIES: + _sum = 0 + stats_templist={} + + try: # if the we have an style warning but we are checking for portability, we have to skip it to prevent KeyError + for filename in stats_countlist: + try: # also bail out if we have a file with no sev-results + _sum += stats_countlist[filename][sev] + stats_templist[filename] = (int)(stats_countlist[filename][sev]) # file : amount, + except KeyError: + continue + if (_sum == 0): # don't print "0 style" etc, if no style warnings were found + break + except KeyError: + continue + stats_file.write("

Top 10 files for " + sev + " severity, total findings: " + str(_sum) + "
\n") + + + # sort, so that the file with the most severities per type is first + stats_list_sorted = sorted(stats_templist.items(), key=operator.itemgetter(1,0), reverse=True) + it = 0 + LENGTH = 0 + + for i in stats_list_sorted: # printing loop + # for aesthetics: if it's the first iteration of the loop, get the max length of the number string + if (it == 0): + LENGTH = len(str(i[1])) # <- length of longest number, now get the difference and try to make other numbers align to it + + stats_file.write(" "*3 + str(i[1]) + " "*(1 + LENGTH - len(str(i[1]))) + " " + i[0] + "
\n") + it += 1 + if (it == 10): # print only the top 10 + break + stats_file.write("

\n") + print("\nOpen '" + options.report_dir + "/index.html' to see the results.") +