1#! /usr/bin/env python3 2 3"""Transform gprof(1) output into useful HTML.""" 4 5import html 6import os 7import re 8import sys 9import webbrowser 10 11header = """\ 12<html> 13<head> 14 <title>gprof output (%s)</title> 15</head> 16<body> 17<pre> 18""" 19 20trailer = """\ 21</pre> 22</body> 23</html> 24""" 25 26def add_escapes(filename): 27 with open(filename) as fp: 28 for line in fp: 29 yield html.escape(line) 30 31def gprof2html(input, output, filename): 32 output.write(header % filename) 33 for line in input: 34 output.write(line) 35 if line.startswith(" time"): 36 break 37 labels = {} 38 for line in input: 39 m = re.match(r"(.* )(\w+)\n", line) 40 if not m: 41 output.write(line) 42 break 43 stuff, fname = m.group(1, 2) 44 labels[fname] = fname 45 output.write('%s<a name="flat:%s" href="#call:%s">%s</a>\n' % 46 (stuff, fname, fname, fname)) 47 for line in input: 48 output.write(line) 49 if line.startswith("index % time"): 50 break 51 for line in input: 52 m = re.match(r"(.* )(\w+)(( <cycle.*>)? \[\d+\])\n", line) 53 if not m: 54 output.write(line) 55 if line.startswith("Index by function name"): 56 break 57 continue 58 prefix, fname, suffix = m.group(1, 2, 3) 59 if fname not in labels: 60 output.write(line) 61 continue 62 if line.startswith("["): 63 output.write('%s<a name="call:%s" href="#flat:%s">%s</a>%s\n' % 64 (prefix, fname, fname, fname, suffix)) 65 else: 66 output.write('%s<a href="#call:%s">%s</a>%s\n' % 67 (prefix, fname, fname, suffix)) 68 for line in input: 69 for part in re.findall(r"(\w+(?:\.c)?|\W+)", line): 70 if part in labels: 71 part = '<a href="#call:%s">%s</a>' % (part, part) 72 output.write(part) 73 output.write(trailer) 74 75 76def main(): 77 filename = "gprof.out" 78 if sys.argv[1:]: 79 filename = sys.argv[1] 80 outputfilename = filename + ".html" 81 input = add_escapes(filename) 82 with open(outputfilename, "w") as output: 83 gprof2html(input, output, filename) 84 webbrowser.open("file:" + os.path.abspath(outputfilename)) 85 86if __name__ == '__main__': 87 main() 88