1
0
Fork 0

Count the bugs reported by PVS-Studio

This commit is contained in:
krcroft 2020-01-14 22:34:23 -08:00 committed by Patryk Obara
parent 7c4c246082
commit 9df802fd56
2 changed files with 95 additions and 4 deletions

View file

@ -94,19 +94,32 @@ jobs:
sudo dpkg -i "pvs-package/pvs.deb"
pvs-studio-analyzer credentials "${{ secrets.PvsStudioName }}" "${{ secrets.PvsStudioKey }}"
- name: Build
run: pvs-studio-analyzer trace -- ./scripts/build.sh -c gcc -t debug
run: |
set -xeu
./autogen.sh
export FLAGS="-Og"
./configure CFLAGS="${FLAGS}" CXXFLAGS="${FLAGS}"
pvs-studio-analyzer trace -- make
- name: Analyze
run: |
set -xeu
pvs-studio-analyzer analyze -o pvs-analysis.log -j "$(nproc)"
plog-converter -a "64:1;OP:1,2,3;CS:1;MISRA:1,2" \
-p "dosbox-staging" -v "${GITHUB_SHA:0:8}" -t "fullhtml" \
-d "V1042" -o "pvs-analysis-report" "pvs-analysis.log"
criteria="GA:1,2;64:1;OP:1,2,3;CS:1;MISRA:1,2"
plog-converter -a "${criteria}" -d V1042 -t csv -o pvs-report.csv pvs-analysis.log
plog-converter -a "${criteria}" -d V1042 -t fullhtml -p dosbox-staging \
-v "${GITHUB_SHA:0:8}" -o pvs-analysis-report pvs-analysis.log
- name: Upload report
uses: actions/upload-artifact@master
with:
name: pvs-analysis-report
path: pvs-analysis-report
- name: Summarize report
env:
MAX_BUGS: 356
run: |
echo "Full report is included in build Artifacts"
echo
./scripts/count-pvs-bugs.py pvs-report.csv "${MAX_BUGS}"
dynamic_matrix:
name: ${{ matrix.compiler }} dynamic sanitizers

78
scripts/count-pvs-bugs.py Executable file
View file

@ -0,0 +1,78 @@
#!/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 int keys and a list of string values, where the:
- keys are V### PVS-Studio error codes
- values are the message of the issue as found in a specific file
"""
issues = collections.defaultdict(list)
with open(filename) as csvfile:
reader = csv.DictReader(csvfile)
for row in reader:
full = row['ErrorCode'] # extract the full code as an URL string
code = full[full.rfind('V'):full.rfind('"')] # get the trailing "V###" code
if code.startswith('V'):
# Convert the V### string into an integer for easy sorting
issues[int(code[1:])].append(row['Message'])
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(len(messages) for messages in issues.values())
if tally > 0:
# Step through the codes and summarize
print("Issues are tallied and sorted by code:\n")
print(" code | issue-string in common to all instances | tally")
print(" ----- --------------------------------------------- -----")
for code in sorted(issues.keys()):
messages = issues[code]
in_common = os.path.commonprefix(messages)[:45]
if len(in_common.split(' ')) < 4:
in_common = 'N/A (too little in-common between issues)'
print(f' [{code:4}] {in_common:45} : {len(messages)}')
# 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))