31 SECTION_SEPERATOR =
'-' * 80
34 """Returns whether a line should be considered to be an instruction."""
50 def merge(callgrind_files, srcs):
51 """Calls callgrind_annotate over the set of callgrind output
52 |callgrind_files| using the sources |srcs| and merges the results
55 for file
in callgrind_files:
56 data = subprocess.check_output([
'callgrind_annotate', file] + srcs)
57 out +=
'%s\n%s\n' % (data, SECTION_SEPERATOR)
60 def parse(filename, data, current):
61 """Parses an annotated execution flow |data| from callgrind_annotate for
62 source |filename| and updates the current execution counts from |current|."""
63 with open(filename)
as f:
64 source = f.read().
split(
'\n')
68 out = [0
if is_asm(l)
else None for l
in source]
78 if l.startswith(
'-- line'):
79 line =
int(l.split(
' ')[2]) - 1
80 elif l.strip() ==
'Ir':
82 elif line !=
None and l.strip()
and '=>' not in l
and 'unidentified lines' not in l:
83 count = l.split(
' ')[0].replace(
',',
'').replace(
'.',
'0')
84 instruction = l.split(
' ', 1)[1].strip()
85 if count !=
'0' or is_asm(instruction):
88 out[line] +=
int(count)
95 """Parses the merged callgrind_annotate output |data| and generates execution
96 counts for all annotated files."""
98 data = [p.strip()
for p
in data.split(SECTION_SEPERATOR)]
105 if 'User-annotated source' in data[i]
and i <
len(data) - 1:
106 filename = data[i].
split(
':', 1)[1].strip()
108 if filename
not in out:
110 if 'No information' in res:
113 res = res.split(
'\n')
114 out[filename] =
parse(filename, res, out[filename])
118 """Takes a dictionary |data| of filenames and execution counts and generates
119 a LCOV coverage output."""
121 for filename, counts
in data.iteritems():
122 out +=
'SF:%s\n' % (os.path.abspath(filename))
123 for line, count
in enumerate(counts):
125 out +=
'DA:%d,%s\n' % (line + 1, count)
126 out +=
'end_of_record\n'
129 if __name__ ==
'__main__':
130 if len(sys.argv) != 3:
131 print '%s <Callgrind Folder> <Build Folder>' % (__file__)
134 cg_folder = sys.argv[1]
135 build_folder = sys.argv[2]
138 for (cwd, _, files)
in os.walk(cg_folder):
140 if f.startswith(
'callgrind.out'):
141 cg_files.append(os.path.abspath(os.path.join(cwd, f)))
144 for (cwd, _, files)
in os.walk(build_folder):
146 fn = os.path.join(cwd, f)
147 if fn.endswith(
'.S'):