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 31 32def main(): 33 filename = "gprof.out" 34 if sys.argv[1:]: 35 filename = sys.argv[1] 36 outputfilename = filename + ".html" 37 input = add_escapes(filename) 38 output = open(outputfilename, "w") 39 output.write(header % filename) 40 for line in input: 41 output.write(line) 42 if line.startswith(" time"): 43 break 44 labels = {} 45 for line in input: 46 m = re.match(r"(.* )(\w+)\n", line) 47 if not m: 48 output.write(line) 49 break 50 stuff, fname = m.group(1, 2) 51 labels[fname] = fname 52 output.write('%s<a name="flat:%s" href="#call:%s">%s</a>\n' % 53 (stuff, fname, fname, fname)) 54 for line in input: 55 output.write(line) 56 if line.startswith("index % time"): 57 break 58 for line in input: 59 m = re.match(r"(.* )(\w+)(( <cycle.*>)? \[\d+\])\n", line) 60 if not m: 61 output.write(line) 62 if line.startswith("Index by function name"): 63 break 64 continue 65 prefix, fname, suffix = m.group(1, 2, 3) 66 if fname not in labels: 67 output.write(line) 68 continue 69 if line.startswith("["): 70 output.write('%s<a name="call:%s" href="#flat:%s">%s</a>%s\n' % 71 (prefix, fname, fname, fname, suffix)) 72 else: 73 output.write('%s<a href="#call:%s">%s</a>%s\n' % 74 (prefix, fname, fname, suffix)) 75 for line in input: 76 for part in re.findall(r"(\w+(?:\.c)?|\W+)", line): 77 if part in labels: 78 part = '<a href="#call:%s">%s</a>' % (part, part) 79 output.write(part) 80 output.write(trailer) 81 output.close() 82 webbrowser.open("file:" + os.path.abspath(outputfilename)) 83 84if __name__ == '__main__': 85 main() 86