xref: /btstack/tool/metrics/metrics-lizard.py (revision 78e65fa66c8fc7ec8eb698d3d88e1fb91c2c84c6)
1#!/usr/bin/env python3
2
3# requires https://github.com/terryyin/lizard
4
5import lizard
6import os
7import sys
8
9folders = [
10'src',
11'src/ble',
12'src/ble/gatt-service',
13'src/classic',
14]
15
16metrics = {}
17targets = {}
18
19targets['CCN']   = 10
20targets['PARAM'] = 7
21
22def metric_sum(name, value):
23    global metrics
24    old = 0
25    if name in metrics:
26        old = metrics[name]
27    metrics[name] = old + value
28
29
30def metric_list(name, item):
31    global metrics
32    value = []
33    if name in metrics:
34        value = metrics[name]
35    value.append(item)
36    metrics[name] = value
37
38def metric_max(name, max):
39    global metrics
40    if name in metrics:
41        if metrics[name] > max:
42            return
43    metrics[name] = max
44
45def metric_measure(metric_name, function_name, actual):
46    metric_max(metric_name + '_MAX', actual)
47    if metric_name in targets:
48        metric_sum(metric_name + '_SUM', actual)
49        if actual > targets[metric_name]:
50            metric_sum(metric_name + '_DEVIATIONS', 1)
51            metric_list(metric_name + '_LIST', function_name)
52
53def analyze_file(path):
54    l = lizard.analyze_file(path)
55    for f in l.function_list:
56        metric_sum('FUNC', 1)
57        metric_measure('PARAM', f.name, f.parameter_count)
58        metric_measure('CCN',   f.name, f.cyclomatic_complexity )
59
60def analyze_folder(folder_path):
61    for file in sorted(os.listdir(folder_path)):
62        if file.endswith(".c"):
63            analyze_file(folder_path+'/'+file)
64
65# find root
66btstack_root = os.path.abspath(os.path.dirname(sys.argv[0]) + '/../..')
67
68print ("Targets:")
69for key,value in sorted(targets.items()):
70    print ('- %-20s: %u' % (key, value))
71
72print ("\nAnalyzing:")
73for path in folders:
74    print('- %s' % path)
75    analyze_folder(btstack_root + "/" + path)
76
77print ("\nResult:")
78
79num_funcs = metrics['FUNC']
80for key,value in sorted(metrics.items()):
81    if key.endswith('LIST'):
82        continue
83    if key.endswith('_SUM'):
84        average = 1.0 * value / num_funcs
85        metric = key.replace('_SUM','_AVERAGE')
86        print ('- %-20s: %4.3f' % (metric, average))
87    else:
88        print ('- %-20s: %5u' % (key, value))
89
90for key,value in sorted(metrics.items()):
91    if not key.endswith('LIST'):
92        continue
93    print ("\n%s" % key)
94    print ('\n'.join(value))
95
96