1*1debfc3dSmrg#! /usr/bin/python 2*1debfc3dSmrg# 3*1debfc3dSmrg# Print a report on which libgccjit.so symbols are used in which test 4*1debfc3dSmrg# cases, and which lack test coverage. Tested with Python 2.7 and 3.2 5*1debfc3dSmrg# To be run from the root directory of the source tree. 6*1debfc3dSmrg# 7*1debfc3dSmrg# Copyright (C) 2014 Free Software Foundation, Inc. 8*1debfc3dSmrg# Written by David Malcolm <dmalcolm@redhat.com>. 9*1debfc3dSmrg# 10*1debfc3dSmrg# This script is Free Software, and it can be copied, distributed and 11*1debfc3dSmrg# modified as defined in the GNU General Public License. A copy of 12*1debfc3dSmrg# its license can be downloaded from http://www.gnu.org/copyleft/gpl.html 13*1debfc3dSmrg 14*1debfc3dSmrgfrom collections import Counter 15*1debfc3dSmrgimport glob 16*1debfc3dSmrgimport re 17*1debfc3dSmrgimport sys 18*1debfc3dSmrg 19*1debfc3dSmrgdef parse_map_file(path): 20*1debfc3dSmrg """ 21*1debfc3dSmrg Parse libgccjit.map, returning the symbols in the API as a list of str. 22*1debfc3dSmrg """ 23*1debfc3dSmrg syms = [] 24*1debfc3dSmrg with open(path) as f: 25*1debfc3dSmrg for line in f: 26*1debfc3dSmrg m = re.match('^\s+([a-z_]+);$', line) 27*1debfc3dSmrg if m: 28*1debfc3dSmrg syms.append(m.group(1)) 29*1debfc3dSmrg return syms 30*1debfc3dSmrg 31*1debfc3dSmrgdef parse_test_case(path): 32*1debfc3dSmrg """ 33*1debfc3dSmrg Locate all symbol-like things in a C test case, yielding 34*1debfc3dSmrg them as a sequence of str. 35*1debfc3dSmrg """ 36*1debfc3dSmrg with open(path) as f: 37*1debfc3dSmrg for line in f: 38*1debfc3dSmrg for m in re.finditer('([_A-Za-z][_A-Za-z0-9]*)', line): 39*1debfc3dSmrg yield m.group(1) 40*1debfc3dSmrg 41*1debfc3dSmrgdef find_test_cases(): 42*1debfc3dSmrg for path in glob.glob('gcc/testsuite/jit.dg/*.[ch]'): 43*1debfc3dSmrg yield path 44*1debfc3dSmrg 45*1debfc3dSmrgapi_syms = parse_map_file('gcc/jit/libgccjit.map') 46*1debfc3dSmrg 47*1debfc3dSmrgsyms_in_test_cases = {} 48*1debfc3dSmrgfor path in find_test_cases(): 49*1debfc3dSmrg syms_in_test_cases[path] = list(parse_test_case(path)) 50*1debfc3dSmrg 51*1debfc3dSmrguses = Counter() 52*1debfc3dSmrgfor sym in sorted(api_syms): 53*1debfc3dSmrg print('symbol: %s' % sym) 54*1debfc3dSmrg uses[sym] = 0 55*1debfc3dSmrg for path in syms_in_test_cases: 56*1debfc3dSmrg count = syms_in_test_cases[path].count(sym) 57*1debfc3dSmrg uses[sym] += count 58*1debfc3dSmrg if count: 59*1debfc3dSmrg print(' uses in %s: %i' % (path, count)) 60*1debfc3dSmrg if uses[sym] == 0: 61*1debfc3dSmrg print(' NEVER USED') 62*1debfc3dSmrg sys.stdout.write('\n') 63*1debfc3dSmrg 64*1debfc3dSmrglayout = '%40s %5s %s' 65*1debfc3dSmrgprint(layout % ('SYMBOL', 'USES', 'HISTOGRAM')) 66*1debfc3dSmrgfor sym, count in uses.most_common(): 67*1debfc3dSmrg print(layout % (sym, count, '*' * count if count else 'UNUSED')) 68