htmlreport: Add HTML validation and fix syntax errors (#2317)
Add HTML validation with HTML Tidy for the resulting files index.html and stats.html. Fix syntax errors found by the validator. Fix that the links in the footer are not clickable by removing the "height: 75%;" style for the classes "menu" and "menu_index". Add some line breaks to the HTML output for better readability and for easier debugging.
This commit is contained in:
parent
91a4bcd71e
commit
4f927ea6c7
|
@ -20,7 +20,7 @@ env:
|
||||||
before_install:
|
before_install:
|
||||||
# install needed deps
|
# install needed deps
|
||||||
- travis_retry sudo apt-get update -qq
|
- travis_retry sudo apt-get update -qq
|
||||||
- travis_retry sudo apt-get install -qq python3-pip qt5-default qt5-qmake qtbase5-dev qtcreator libxml2-utils libpcre3 gdb unzip wx-common xmlstarlet python3-dev liblua5.3-dev libcurl3 libcairo2-dev libsigc++-2.0-dev
|
- travis_retry sudo apt-get install -qq python3-pip qt5-default qt5-qmake qtbase5-dev qtcreator libxml2-utils libpcre3 gdb unzip wx-common xmlstarlet python3-dev liblua5.3-dev libcurl3 libcairo2-dev libsigc++-2.0-dev tidy
|
||||||
# Python 2 modules
|
# Python 2 modules
|
||||||
- travis_retry python2 -m pip install --user pytest==4.6.4
|
- travis_retry python2 -m pip install --user pytest==4.6.4
|
||||||
- travis_retry python2 -m pip install --user pylint
|
- travis_retry python2 -m pip install --user pylint
|
||||||
|
|
|
@ -1,24 +1,54 @@
|
||||||
#!/bin/bash -ex
|
#!/bin/bash -ex
|
||||||
|
|
||||||
|
# Command for checking HTML syntax with HTML Tidy, see http://www.html-tidy.org/
|
||||||
|
# newer tidy (5.6.0) command, if using this it is not necessary to ignore warnings:
|
||||||
|
#tidy_cmd='tidy -o /dev/null -eq --drop-empty-elements no'
|
||||||
|
# older tidy from 2009 (Ubuntu 16.04 Xenial comes with this old version):
|
||||||
|
tidy_cmd='tidy -o /dev/null -eq'
|
||||||
|
|
||||||
|
function validate_html {
|
||||||
|
set +e
|
||||||
|
${tidy_cmd} $1
|
||||||
|
tidy_status=$?
|
||||||
|
set -e
|
||||||
|
if [ $tidy_status -eq 2 ]; then
|
||||||
|
echo "HTML does not validate!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
./cppcheck-htmlreport --file ../gui/test/data/xmlfiles/xmlreport_v2.xml --title "xml2 test" --report-dir . --source-dir ../test/
|
./cppcheck-htmlreport --file ../gui/test/data/xmlfiles/xmlreport_v2.xml --title "xml2 test" --report-dir . --source-dir ../test/
|
||||||
echo -e "\n"
|
echo -e "\n"
|
||||||
|
# Check HTML syntax
|
||||||
|
validate_html index.html
|
||||||
|
validate_html stats.html
|
||||||
|
|
||||||
|
|
||||||
../cppcheck ../gui/test --enable=all --inconclusive --xml-version=2 2> gui_test.xml
|
../cppcheck ../gui/test --enable=all --inconclusive --xml-version=2 2> gui_test.xml
|
||||||
xmllint --noout gui_test.xml
|
xmllint --noout gui_test.xml
|
||||||
./cppcheck-htmlreport --file ./gui_test.xml --title "xml2 + inconclusive test" --report-dir .
|
./cppcheck-htmlreport --file ./gui_test.xml --title "xml2 + inconclusive test" --report-dir .
|
||||||
echo ""
|
echo ""
|
||||||
|
# Check HTML syntax
|
||||||
|
validate_html index.html
|
||||||
|
validate_html stats.html
|
||||||
|
|
||||||
|
|
||||||
../cppcheck ../gui/test --enable=all --inconclusive --verbose --xml-version=2 2> gui_test.xml
|
../cppcheck ../gui/test --enable=all --inconclusive --verbose --xml-version=2 2> gui_test.xml
|
||||||
xmllint --noout gui_test.xml
|
xmllint --noout gui_test.xml
|
||||||
./cppcheck-htmlreport --file ./gui_test.xml --title "xml2 + inconclusive + verbose test" --report-dir .
|
./cppcheck-htmlreport --file ./gui_test.xml --title "xml2 + inconclusive + verbose test" --report-dir .
|
||||||
echo -e "\n"
|
echo -e "\n"
|
||||||
|
# Check HTML syntax
|
||||||
|
validate_html index.html
|
||||||
|
validate_html stats.html
|
||||||
|
|
||||||
|
|
||||||
../cppcheck --errorlist --inconclusive --xml-version=2 > errorlist.xml
|
../cppcheck --errorlist --inconclusive --xml-version=2 > errorlist.xml
|
||||||
xmllint --noout errorlist.xml
|
xmllint --noout errorlist.xml
|
||||||
./cppcheck-htmlreport --file ./errorlist.xml --title "errorlist" --report-dir .
|
./cppcheck-htmlreport --file ./errorlist.xml --title "errorlist" --report-dir .
|
||||||
|
# Check HTML syntax
|
||||||
|
validate_html index.html
|
||||||
|
validate_html stats.html
|
||||||
|
|
||||||
|
|
||||||
../cppcheck ../samples/memleak/good.c ../samples/resourceLeak/good.c --xml-version=2 --enable=information --suppressions-list=test_suppressions.txt --xml 2> unmatchedSuppr.xml
|
../cppcheck ../samples/memleak/good.c ../samples/resourceLeak/good.c --xml-version=2 --enable=information --suppressions-list=test_suppressions.txt --xml 2> unmatchedSuppr.xml
|
||||||
xmllint --noout unmatchedSuppr.xml
|
xmllint --noout unmatchedSuppr.xml
|
||||||
|
@ -27,3 +57,6 @@ grep "unmatchedSuppression<.*>information<.*>Unmatched suppression: variableScop
|
||||||
grep ">unmatchedSuppression</.*>information<.*>Unmatched suppression: uninitstring<" index.html
|
grep ">unmatchedSuppression</.*>information<.*>Unmatched suppression: uninitstring<" index.html
|
||||||
grep "notexisting" index.html
|
grep "notexisting" index.html
|
||||||
grep ">unmatchedSuppression<.*>information<.*>Unmatched suppression: \*<" index.html
|
grep ">unmatchedSuppression<.*>information<.*>Unmatched suppression: \*<" index.html
|
||||||
|
# Check HTML syntax
|
||||||
|
validate_html index.html
|
||||||
|
validate_html stats.html
|
||||||
|
|
|
@ -90,7 +90,7 @@ div.verbose div.content {
|
||||||
margin-top: 5px;
|
margin-top: 5px;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
width: 150px;
|
width: 150px;
|
||||||
height: 75%;
|
/*height: 75%;*/
|
||||||
position: fixed;
|
position: fixed;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
|
@ -102,7 +102,7 @@ div.verbose div.content {
|
||||||
padding-left: 5px;
|
padding-left: 5px;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
width: 300px;
|
width: 300px;
|
||||||
height: 75%;
|
/*height: 75%;*/
|
||||||
position: fixed;
|
position: fixed;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
|
@ -259,7 +259,7 @@ HTML_FOOTER = """
|
||||||
</br>
|
</br>
|
||||||
Internet: <a href="http://cppcheck.net">http://cppcheck.net</a></br>
|
Internet: <a href="http://cppcheck.net">http://cppcheck.net</a></br>
|
||||||
IRC: <a href="irc://irc.freenode.net/cppcheck">irc://irc.freenode.net/cppcheck</a></br>
|
IRC: <a href="irc://irc.freenode.net/cppcheck">irc://irc.freenode.net/cppcheck</a></br>
|
||||||
<p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -573,24 +573,23 @@ if __name__ == '__main__':
|
||||||
except IndexError:
|
except IndexError:
|
||||||
cnt_min = 0
|
cnt_min = 0
|
||||||
|
|
||||||
stat_fmt = " <tr><td><input type='checkbox' onclick='toggle_class_visibility(this.id)' id='{}' name='{}' checked></td><td>{}</td><td>{}</td></tr>"
|
stat_fmt = "\n <tr><td><input type='checkbox' onclick='toggle_class_visibility(this.id)' id='{}' name='{}' checked></td><td>{}</td><td>{}</td></tr>"
|
||||||
for occurrences in reversed(range(cnt_min, cnt_max + 1)):
|
for occurrences in reversed(range(cnt_min, cnt_max + 1)):
|
||||||
for _id in [k for k, v in sorted(counter.items()) if v == occurrences]:
|
for _id in [k for k, v in sorted(counter.items()) if v == occurrences]:
|
||||||
stat_html.append(stat_fmt.format(_id, _id, dict(counter.most_common())[_id], _id))
|
stat_html.append(stat_fmt.format(_id, _id, dict(counter.most_common())[_id], _id))
|
||||||
|
|
||||||
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(HTML_HEAD.replace('id="menu" dir="rtl"', 'id="menu_index"', 1).replace("Defects:", "Defect summary;", 1) % (options.title, '', options.title, '', ''))
|
||||||
output_file.write(' <table>')
|
output_file.write('\n <label><input type="checkbox" onclick="toggle_all()" checked> Toggle all</label>')
|
||||||
output_file.write(' <tr><th>Show</th><th>#</th><th>Defect ID</th></tr>')
|
output_file.write('\n <table>')
|
||||||
output_file.write('<label><input type="checkbox" onclick="toggle_all()" checked/> Toggle all</label>')
|
output_file.write('\n <tr><th>Show</th><th>#</th><th>Defect ID</th></tr>')
|
||||||
output_file.write(''.join(stat_html))
|
output_file.write(''.join(stat_html))
|
||||||
output_file.write(' <tr><td></td><td>' + str(stats_count) + '</td><td>total</td></tr>')
|
output_file.write('\n <tr><td></td><td>' + str(stats_count) + '</td><td>total</td></tr>')
|
||||||
output_file.write(' </table>')
|
output_file.write('\n </table>')
|
||||||
output_file.write(' <a href="stats.html">Statistics</a></p>')
|
output_file.write('\n <p><a href="stats.html">Statistics</a></p>')
|
||||||
output_file.write(HTML_HEAD_END.replace("content", "content_index", 1))
|
output_file.write(HTML_HEAD_END.replace("content", "content_index", 1))
|
||||||
output_file.write(' <table>\n')
|
|
||||||
|
|
||||||
output_file.write(
|
output_file.write('\n <table>')
|
||||||
' <tr><th>Line</th><th>Id</th><th>CWE</th><th>Severity</th><th>Message</th></tr>')
|
output_file.write('\n <tr><th>Line</th><th>Id</th><th>CWE</th><th>Severity</th><th>Message</th></tr>')
|
||||||
for filename, data in sorted(files.items()):
|
for filename, data in sorted(files.items()):
|
||||||
if filename in decode_errors: # don't print a link but a note
|
if filename in decode_errors: # don't print a link but a note
|
||||||
output_file.write("\n <tr><td colspan='5'>%s</td></tr>" % (filename))
|
output_file.write("\n <tr><td colspan='5'>%s</td></tr>" % (filename))
|
||||||
|
@ -625,18 +624,18 @@ if __name__ == '__main__':
|
||||||
if error['id'] == 'missingInclude':
|
if error['id'] == 'missingInclude':
|
||||||
output_file.write(
|
output_file.write(
|
||||||
'\n <tr class="%s"><td></td><td>%s</td><td></td><td>%s</td><td>%s</td></tr>' %
|
'\n <tr class="%s"><td></td><td>%s</td><td></td><td>%s</td><td>%s</td></tr>' %
|
||||||
(error['id'], error['id'], error['severity'], error['msg']))
|
(error['id'], error['id'], error['severity'], html_escape(error['msg'])))
|
||||||
elif (error['id'] == 'unmatchedSuppression') and filename.endswith('*'):
|
elif (error['id'] == 'unmatchedSuppression') and filename.endswith('*'):
|
||||||
output_file.write(
|
output_file.write(
|
||||||
'\n <tr class="%s"><td></td><td>%s</td><td></td><td>%s</td><td %s>%s</td></tr>' %
|
'\n <tr class="%s"><td></td><td>%s</td><td></td><td>%s</td><td %s>%s</td></tr>' %
|
||||||
(error['id'], error['id'], error['severity'], error_class,
|
(error['id'], error['id'], error['severity'], error_class,
|
||||||
error['msg']))
|
html_escape(error['msg'])))
|
||||||
else:
|
else:
|
||||||
output_file.write(
|
output_file.write(
|
||||||
'\n <tr class="%s"><td><a href="%s#line-%d">%d</a></td><td>%s</td><td>%s</td><td>%s</td><td %s>%s</td></tr>' %
|
'\n <tr class="%s"><td><a href="%s#line-%d">%d</a></td><td>%s</td><td>%s</td><td>%s</td><td %s>%s</td></tr>' %
|
||||||
(error['id'], data['htmlfile'], error['line'], error['line'],
|
(error['id'], data['htmlfile'], error['line'], error['line'],
|
||||||
error['id'], cwe_url, error['severity'], error_class,
|
error['id'], cwe_url, error['severity'], error_class,
|
||||||
error['msg']))
|
html_escape(error['msg'])))
|
||||||
|
|
||||||
output_file.write('\n </table>')
|
output_file.write('\n </table>')
|
||||||
output_file.write(HTML_FOOTER % contentHandler.versionCppcheck)
|
output_file.write(HTML_FOOTER % contentHandler.versionCppcheck)
|
||||||
|
@ -707,4 +706,6 @@ if __name__ == '__main__':
|
||||||
break
|
break
|
||||||
stats_file.write("</p>\n")
|
stats_file.write("</p>\n")
|
||||||
|
|
||||||
|
stats_file.write(HTML_FOOTER % contentHandler.versionCppcheck)
|
||||||
|
|
||||||
print("\nOpen '" + options.report_dir + "/index.html' to see the results.")
|
print("\nOpen '" + options.report_dir + "/index.html' to see the results.")
|
||||||
|
|
Loading…
Reference in New Issue