1
0
Fork 0
dosbox-staging/scripts/count-pvs-bugs.py
krcroft 65d8187595 Test more criteria during PVS analysis
This commit:

- Adds a separate analysis run against the MIRSA (Motor Industry
  Software Reliability Association) criteria, which is extremely
  thorough. This tally is not summarized or considered fatal to the
  workflow. It runs virtually instantly, and the results are very
  interesting; however are too numerous to include in our general
  analysis (ie: over 13,000 issues).

- Changes the PVS summary script output to a tally-per-file instead
  of trying to summarize the nature of the issue, which was mostly
  unhelpful without the full text.

- Adds the full list of possible supressible issue to the report
  directory, so if further suppressions are needed then these will be
  easy to find and use.

- Adds one dr_flac suppression per the resolution here:
  mackron/dr_libs#117
2020-01-29 14:59:50 +01:00

74 lines
2 KiB
Python
Executable file

#!/usr/bin/python3
# Copyright (C) 2020 Kevin Croft <krcroft@gmail.com>
# SPDX-License-Identifier: GPL-2.0-or-later
"""
Count the number of issues found in an PVS-Studio report.
Usage: count-pvs-issues.py REPORT [MAX-ISSUES]
Where:
- REPORT is a file in CSV-format
- MAX-ISSUES is as a positive integer indicating the maximum
issues that should be permitted before returning failure
to the shell. Default is non-limit.
"""
# pylint: disable=invalid-name
# pylint: disable=missing-docstring
import collections
import csv
import os
import sys
def parse_issues(filename):
"""
Returns a dict of source filename keys having occurrence-count values
"""
cwd = os.getcwd()
issues = collections.defaultdict(int)
with open(filename) as csvfile:
reader = csv.DictReader(csvfile)
for row in reader:
sourcefile = os.path.realpath(row['FilePath'])
# Skip non-file lines
if not sourcefile.startswith('/'):
continue
sourcefile = os.path.relpath(sourcefile, cwd)
issues[sourcefile] += 1
return issues
def main(argv):
# assume success until proven otherwise
rcode = 0
# Get the issues and the total tally
issues = parse_issues(argv[1])
tally = sum(issues.values())
if tally > 0:
# find the longest source filename
longest_name = max(len(sourcefile) for sourcefile in issues.keys())
# Print the source filenames and their issue counts
print("Sorted by issue count:\n")
for sourcefile in sorted(issues, key=issues.get, reverse=True):
print(f' {sourcefile:{longest_name}} : {issues[sourcefile]}')
# Print the tally against the desired maximum
if len(sys.argv) == 3:
max_issues = int(sys.argv[2])
print(f'\nTotal: {tally} issues (out of {max_issues} allowed)')
if tally > max_issues:
rcode = 1
else:
print(f'\nTotal: {tally} issues')
return rcode
if __name__ == "__main__":
sys.exit(main(sys.argv))