xref: /btstack/tool/metrics/metrics-lizard.py (revision 78e65fa66c8fc7ec8eb698d3d88e1fb91c2c84c6)
138e38f23SMatthias Ringwald#!/usr/bin/env python3
238e38f23SMatthias Ringwald
338e38f23SMatthias Ringwald# requires https://github.com/terryyin/lizard
438e38f23SMatthias Ringwald
538e38f23SMatthias Ringwaldimport lizard
638e38f23SMatthias Ringwaldimport os
738e38f23SMatthias Ringwaldimport sys
838e38f23SMatthias Ringwald
938e38f23SMatthias Ringwaldfolders = [
1038e38f23SMatthias Ringwald'src',
1138e38f23SMatthias Ringwald'src/ble',
1238e38f23SMatthias Ringwald'src/ble/gatt-service',
1338e38f23SMatthias Ringwald'src/classic',
1438e38f23SMatthias Ringwald]
1538e38f23SMatthias Ringwald
1638e38f23SMatthias Ringwaldmetrics = {}
1738e38f23SMatthias Ringwaldtargets = {}
1838e38f23SMatthias Ringwald
1938e38f23SMatthias Ringwaldtargets['CCN']   = 10
2038e38f23SMatthias Ringwaldtargets['PARAM'] = 7
2138e38f23SMatthias Ringwald
22*78e65fa6SMatthias Ringwalddef metric_sum(name, value):
2338e38f23SMatthias Ringwald    global metrics
24*78e65fa6SMatthias Ringwald    old = 0
2538e38f23SMatthias Ringwald    if name in metrics:
26*78e65fa6SMatthias Ringwald        old = metrics[name]
27*78e65fa6SMatthias Ringwald    metrics[name] = old + value
2838e38f23SMatthias Ringwald
2938e38f23SMatthias Ringwald
3038e38f23SMatthias Ringwalddef metric_list(name, item):
3138e38f23SMatthias Ringwald    global metrics
3238e38f23SMatthias Ringwald    value = []
3338e38f23SMatthias Ringwald    if name in metrics:
3438e38f23SMatthias Ringwald        value = metrics[name]
3538e38f23SMatthias Ringwald    value.append(item)
3638e38f23SMatthias Ringwald    metrics[name] = value
3738e38f23SMatthias Ringwald
3838e38f23SMatthias Ringwalddef metric_max(name, max):
3938e38f23SMatthias Ringwald    global metrics
4038e38f23SMatthias Ringwald    if name in metrics:
4138e38f23SMatthias Ringwald        if metrics[name] > max:
4238e38f23SMatthias Ringwald            return
4338e38f23SMatthias Ringwald    metrics[name] = max
4438e38f23SMatthias Ringwald
45*78e65fa6SMatthias Ringwalddef metric_measure(metric_name, function_name, actual):
4638e38f23SMatthias Ringwald    metric_max(metric_name + '_MAX', actual)
4738e38f23SMatthias Ringwald    if metric_name in targets:
48*78e65fa6SMatthias Ringwald        metric_sum(metric_name + '_SUM', actual)
4938e38f23SMatthias Ringwald        if actual > targets[metric_name]:
50*78e65fa6SMatthias Ringwald            metric_sum(metric_name + '_DEVIATIONS', 1)
51*78e65fa6SMatthias Ringwald            metric_list(metric_name + '_LIST', function_name)
5238e38f23SMatthias Ringwald
5338e38f23SMatthias Ringwalddef analyze_file(path):
5438e38f23SMatthias Ringwald    l = lizard.analyze_file(path)
5538e38f23SMatthias Ringwald    for f in l.function_list:
56*78e65fa6SMatthias Ringwald        metric_sum('FUNC', 1)
5738e38f23SMatthias Ringwald        metric_measure('PARAM', f.name, f.parameter_count)
5838e38f23SMatthias Ringwald        metric_measure('CCN',   f.name, f.cyclomatic_complexity )
5938e38f23SMatthias Ringwald
6038e38f23SMatthias Ringwalddef analyze_folder(folder_path):
6138e38f23SMatthias Ringwald    for file in sorted(os.listdir(folder_path)):
6238e38f23SMatthias Ringwald        if file.endswith(".c"):
6338e38f23SMatthias Ringwald            analyze_file(folder_path+'/'+file)
6438e38f23SMatthias Ringwald
6538e38f23SMatthias Ringwald# find root
6638e38f23SMatthias Ringwaldbtstack_root = os.path.abspath(os.path.dirname(sys.argv[0]) + '/../..')
6738e38f23SMatthias Ringwald
6838e38f23SMatthias Ringwaldprint ("Targets:")
6938e38f23SMatthias Ringwaldfor key,value in sorted(targets.items()):
7038e38f23SMatthias Ringwald    print ('- %-20s: %u' % (key, value))
7138e38f23SMatthias Ringwald
7238e38f23SMatthias Ringwaldprint ("\nAnalyzing:")
7338e38f23SMatthias Ringwaldfor path in folders:
7438e38f23SMatthias Ringwald    print('- %s' % path)
7538e38f23SMatthias Ringwald    analyze_folder(btstack_root + "/" + path)
7638e38f23SMatthias Ringwald
7738e38f23SMatthias Ringwaldprint ("\nResult:")
7838e38f23SMatthias Ringwald
79*78e65fa6SMatthias Ringwaldnum_funcs = metrics['FUNC']
8038e38f23SMatthias Ringwaldfor key,value in sorted(metrics.items()):
8138e38f23SMatthias Ringwald    if key.endswith('LIST'):
8238e38f23SMatthias Ringwald        continue
83*78e65fa6SMatthias Ringwald    if key.endswith('_SUM'):
84*78e65fa6SMatthias Ringwald        average = 1.0 * value / num_funcs
85*78e65fa6SMatthias Ringwald        metric = key.replace('_SUM','_AVERAGE')
86*78e65fa6SMatthias Ringwald        print ('- %-20s: %4.3f' % (metric, average))
87*78e65fa6SMatthias Ringwald    else:
88*78e65fa6SMatthias Ringwald        print ('- %-20s: %5u' % (key, value))
8938e38f23SMatthias Ringwald
9038e38f23SMatthias Ringwaldfor key,value in sorted(metrics.items()):
9138e38f23SMatthias Ringwald    if not key.endswith('LIST'):
9238e38f23SMatthias Ringwald        continue
9338e38f23SMatthias Ringwald    print ("\n%s" % key)
9438e38f23SMatthias Ringwald    print ('\n'.join(value))
9538e38f23SMatthias Ringwald
96