Skip to content

Commit 8ec8f6f

Browse files
committed
generate 1 log file for per-package info and 1 summary file with aggregated info
1 parent ee9defa commit 8ec8f6f

File tree

1 file changed

+73
-40
lines changed

1 file changed

+73
-40
lines changed

tools/compare-valueflow-options.py

+73-40
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
#!/usr/bin/env python3
22

3-
# Compare "normal" check level and "exhaustive" check level
3+
# Compare results and timings of different valueflow options
4+
# Example usage:
5+
# cd ~/cppcheck && make CXXFLAGS=-O2 MATCHCOMPILER=yes
6+
# python3 compare-valueflow-options.py --cppcheck-path=~/cppcheck --packages-path=~/daca2-packages
47

58
import donate_cpu_lib as lib
69
import argparse
710
import glob
811
import os
12+
import re
913
import sys
1014
import random
1115

@@ -16,6 +20,20 @@ def format_float(a, b=1):
1620
return 'N/A'
1721

1822

23+
def count_errors(errout:str, c:set):
24+
for line in errout.split('\n'):
25+
if not line.endswith(']'):
26+
continue
27+
res = re.match(r'^[^:]+:[0-9]+:[0-9]+: (error|warning|style|portability|performance):.*\[([a-zA-Z0-9_\-]+)\]$', line)
28+
if res is None:
29+
print('No warning? ' + line)
30+
continue
31+
severity = res.group(1)
32+
c[severity] = c.get(severity, 0) + 1
33+
error_id = res.group(2)
34+
c[error_id] = c.get(error_id, 0) + 1
35+
36+
1937
if __name__ == "__main__":
2038
__my_script_name = os.path.splitext(os.path.basename(sys.argv[0]))[0]
2139
__work_path = os.path.expanduser(os.path.join('~', 'cppcheck-' + __my_script_name + '-workfolder'))
@@ -47,20 +65,18 @@ def format_float(a, b=1):
4765

4866
lib.set_jobs('-j' + str(args.j))
4967

50-
def results_file(name):
51-
f, ext = os.path.splitext(args.o)
52-
return os.path.join(work_path, f + '_' + name + ext)
68+
results_file = os.path.join(work_path, args.o)
69+
summary_file = os.path.join(work_path, 'summary.log')
70+
71+
for f in (results_file, summary_file):
72+
if os.path.exists(f):
73+
os.remove(f)
5374

5475
opts = {'0': '--check-level=exhaustive --suppress=valueFlow*',
5576
'it2': '--check-level=exhaustive --performance-valueflow-max-iterations=2 --suppress=valueFlow*',
5677
'it1': '--check-level=exhaustive --performance-valueflow-max-iterations=1 --suppress=valueFlow*',
5778
'if8': '--check-level=exhaustive --performance-valueflow-max-if-count=8 --suppress=valueFlow*'}
5879

59-
for o in opts.keys():
60-
f = results_file(o)
61-
if os.path.exists(f):
62-
os.remove(f)
63-
6480
cppcheck_path = args.cppcheck_path
6581

6682
if cppcheck_path is None:
@@ -94,8 +110,9 @@ def results_file(name):
94110
random.shuffle(packages_idxs)
95111

96112
packages_processed = 0
97-
crashes = []
98-
timeouts = []
113+
summary_results = {}
114+
for id in opts.keys():
115+
summary_results[id] = {}
99116

100117
while (packages_processed < args.p and len(packages_idxs) > 0) or args.packages:
101118
if args.packages:
@@ -117,50 +134,66 @@ def results_file(name):
117134
print("No files to process")
118135
continue
119136

120-
results_to_diff = list()
121-
timings = list()
122-
123-
crashed = []
124-
timeout = []
137+
results0 = None
138+
time0 = None
125139

126140
enable = 'style'
127141
debug_warnings = False
128142

129143
libraries = lib.library_includes.get_libraries(source_path)
130144

145+
with open(results_file, 'at') as myfile:
146+
myfile.write('package:' + package + '\n')
147+
myfile.write('libraries:' + ','.join(libraries) +'\n')
148+
131149
for id, extra_args in opts.items():
132-
print('scan:'+id)
150+
print('scan:' + id)
133151
c, errout, info, time, cppcheck_options, timing_info = lib.scan_package(cppcheck_path, source_path, libraries, enable=enable, extra_args=extra_args)
152+
error_text = None
134153
if c < 0:
135154
if c == -101 and 'error: could not find or open any of the paths given.' in errout:
136155
# No sourcefile found (for example only headers present)
137-
print('Error: 101')
156+
error_text = f'{id} ERR no source file'
138157
elif c == lib.RETURN_CODE_TIMEOUT:
139-
print(id + ' timed out!')
140-
timeout.append(id)
141-
continue # we don't want to compare timeouts
158+
error_text = f'{id} timeout'
142159
else:
143-
print(f'{id} crashed! code={c}')
144-
crashed.append(id)
145-
results_to_diff.append(errout)
146-
timings.append(time)
147-
148-
if len(results_to_diff) <= 1:
149-
continue
160+
error_text = f'{id} crash code={c}'
150161

151-
r0 = results_to_diff[0]
152-
with open(results_file(id), 'a') as myfile:
153-
myfile.write(package + '\n')
154-
if id in crashed:
155-
myfile.write('Crash\n')
156-
elif id in timeout:
157-
myfile.write('Timeout\n')
162+
with open(results_file, 'at') as myfile:
163+
if error_text is not None:
164+
myfile.write(f'{error_text}\n')
158165
else:
159-
diff = lib.diff_results('0', r0, id, errout)
160-
if diff != '':
161-
myfile.write('diff:\n' + diff + '\n')
162-
myfile.write('time: %.1f %.1f\n' % (timings[0], time))
163-
myfile.write('libraries:' + ','.join(libraries) +'\n')
166+
results = {}
167+
count_errors(errout, results)
168+
count_errors(errout, summary_results[id])
169+
if results0 is None:
170+
results0 = results
171+
time0 = time
172+
else:
173+
for error_id, count in results0.items():
174+
current_count = results.get(error_id, 0)
175+
if count > current_count:
176+
myfile.write(f'{id}: FN {error_id}: {current_count} of {count}\n')
177+
if time > 10 or time0 > 10:
178+
myfile.write(f'{id}: Time: %.1f\n' % time)
179+
time_factor = time / time0
180+
myfile.write(f'{id}: Timefactor: %.3f\n' % time_factor)
181+
182+
with open(summary_file, 'wt') as myfile:
183+
all = {}
184+
for id, c in summary_results.items():
185+
for error_id, count in c.items():
186+
if error_id not in all:
187+
all[error_id] = {}
188+
for id2 in opts.keys():
189+
all[error_id][id2] = 0
190+
all[error_id][id] += count
191+
192+
for error_id, id_count in all.items():
193+
myfile.write(f'{error_id}:')
194+
for id, count in id_count.items():
195+
myfile.write(f' {id}:{count}')
196+
myfile.write('\n')
164197

165198
packages_processed += 1
166199
print(str(packages_processed) + ' of ' + str(args.p) + ' packages processed\n')

0 commit comments

Comments
 (0)