#!/usr/bin/python3 """ Print Polyspace results on terminal, for easy review. Copyright (C) 2020-2024 The MathWorks, Inc. """ # SPDX-License-Identifier: Apache-2.0 import argparse import os import sys from collections import Counter def _parse_findings(filename: str, ignore_metrics=True): """Parse CSV file""" csv_sep = '\t' # Polyspace default separator def consume_header(oneline): parts = oneline.split(csv_sep) header.extend([p.strip() for p in parts]) def consume_data(oneline): columns = oneline.split(csv_sep) return dict(zip(header, columns, strict=True)) findings = [] header = [] with open(filename, encoding="latin-1") as fp: for lno, line in enumerate(fp): if lno == 0: consume_header(line.rstrip()) else: onefind = consume_data(line.rstrip()) if onefind and (not ignore_metrics or onefind.get('Family', '') != 'Code Metric'): findings.append(onefind) # -- return findings def print_sorted(mydict, maxlines=0): """Print a dict sorted by value, largest first""" for lno, cnt_and_fil in enumerate( sorted(((cnt, fil) for fil, cnt in mydict.items()), reverse=True), start=1 ): print(f" {cnt_and_fil[0]} issues in {cnt_and_fil[1]}") if lno >= maxlines and maxlines != 0: break def main(argv): # 1. command line arguments as required by your script parser = argparse.ArgumentParser(description='Print results to console', allow_abbrev=False) parser.add_argument('file', type=str, help='output file from polyspace-results-export') parser.add_argument('--details', action='store_true', help='print details') args = parser.parse_args() # 2. parsing the Polyspace files -> report findings = _parse_findings(args.file) print("-= Polyspace Static Code Analysis results =-") # 3. print details if args.details: for f in findings: print( f"{f.get('File', 'unknown file')}:" + f"{f.get('Line', '?')}:" + f"{f.get('Col', '?')}: " + f"{f.get('Family', '')} {f.get('Check', 'Defect')}" ) # 3. summary by category and file print("By type:") family = Counter([f.get('Family', 'Defect') for f in findings]) print_sorted(family) print("Top 10 files:") files = Counter([os.path.basename(f.get('File', 'Unknown')) for f in findings]) print_sorted(files, 10) print(f"SCA found {len(findings)} issues in total") return 0 if __name__ == "__main__": main(sys.argv[1:])