blob: ce680c7b078fd8913b46ebbfa8373affba33f0f4 [file] [log] [blame]
#!/usr/bin/python
from __future__ import division
import sys, os
def getSummary(input):
inputs = [[None,iter(open(input))]]
def getLine(elt):
la,i = elt
if la is None:
try:
ln = i.next()
except StopIteration:
ln = None
except:
raise ValueError("unexpected IO error")
return ln
else:
elt[0] = None
return la
def getLines():
return map(getLine,inputs)
def putback(ln,elt):
assert elt[0] is None
elt[0] = ln
events = None
# read header (up to ob=)
while 1:
lns = getLines()
ln = lns[0]
if ln.startswith('ob='):
break
else:
if ln.startswith('positions:'):
if ln!='positions: instr line\n':
raise ValueError("unexpected 'positions' directive")
elif ln.startswith('events:'):
events = ln[len('events: '):].strip().split(' ')
if events is None:
raise ValueError('missing events directive')
boolTypes = set(['Icov','Iuncov'])
numEvents = len(events)
eventTypes = [e in boolTypes for e in events]
def readCalls():
results = {}
for elt in inputs:
while 1:
ln = getLine(elt)
if ln is not None and (ln.startswith('cfl=') or ln.startswith('cfn=')):
if ln.startswith('cfl='):
cfl = ln
cfn = getLine(elt)
if not cfn.startswith('cfn='):
raise ValueError("unexpected cfl directive without function")
else:
cfl = None
cfn = ln
target = getLine(elt)
if not target.startswith('calls='):
raise ValueError("unexpected cfn directive with calls")
stat = map(int,getLine(elt).strip().split(' '))
key = target
existing = results.get(target)
if existing is None:
results[key] = [cfl,cfn,target,stat]
else:
if existing[0]!=cfl or existing[1]!=cfn:
raise ValueError("multiple call descriptions for a single target")
existing[3] = mergeStats([existing[3],stat])
else:
putback(ln, elt)
break
return results
summed = [0]*len(events)
# read statistics
while 1:
lns = getLines()
ln = lns[0]
if ln is None:
break
elif ln.startswith('fn') or ln.startswith('fl'):
pass
elif ln.strip():
# an actual statistic
data = [map(int,ln.strip().split(' ')) for ln in lns][0]
summed = map(lambda a,b: a+b, data[2:], summed)
# read any associated calls
for cfl,cfn,calls,stat in readCalls().values():
pass
return events,summed
def main(args):
from optparse import OptionParser
op = OptionParser("usage: %prog [options] file")
opts,args = op.parse_args()
total = {}
for i in args:
events,summed = getSummary(i)
for e,s in zip(events,summed):
total[e] = total.get(e,[0,0])
total[e][0] += s
total[e][1] += 1
print '-- %s --'%(i,)
items = zip(events,summed)
items.sort()
for e,s in items:
print '%s: %s'%(e,s)
print '-- totals --'
items = total.items()
table = []
for e,(s,N) in items:
table.append((str(e),str(s),str(N),str(s//N)))
w = map(lambda l: max(map(len,l)), zip(*table))
for (a,b,c,d) in table:
print '%-*s: %*s (in %*s files, avg: %*s)'%(w[0],a,w[1],b,w[2],c,w[3],d)
if __name__=='__main__':
main(sys.argv)