| #! /usr/bin/env python2.3 |
| |
| """Transform gprof(1) output into useful HTML.""" |
| |
| import re, os, sys, cgi, webbrowser |
| |
| header = """\ |
| <html> |
| <head> |
| <title>gprof output (%s)</title> |
| </head> |
| <body> |
| <pre> |
| """ |
| |
| trailer = """\ |
| </pre> |
| </body> |
| </html> |
| """ |
| |
| def add_escapes(input): |
| for line in input: |
| yield cgi.escape(line) |
| |
| def main(): |
| filename = "gprof.out" |
| if sys.argv[1:]: |
| filename = sys.argv[1] |
| outputfilename = filename + ".html" |
| input = add_escapes(file(filename)) |
| output = file(outputfilename, "w") |
| output.write(header % filename) |
| for line in input: |
| output.write(line) |
| if line.startswith(" time"): |
| break |
| labels = {} |
| for line in input: |
| m = re.match(r"(.* )(\w+)\n", line) |
| if not m: |
| output.write(line) |
| break |
| stuff, fname = m.group(1, 2) |
| labels[fname] = fname |
| output.write('%s<a name="flat:%s" href="#call:%s">%s</a>\n' % |
| (stuff, fname, fname, fname)) |
| for line in input: |
| output.write(line) |
| if line.startswith("index % time"): |
| break |
| for line in input: |
| m = re.match(r"(.* )(\w+)(( <cycle.*>)? \[\d+\])\n", line) |
| if not m: |
| output.write(line) |
| if line.startswith("Index by function name"): |
| break |
| continue |
| prefix, fname, suffix = m.group(1, 2, 3) |
| if fname not in labels: |
| output.write(line) |
| continue |
| if line.startswith("["): |
| output.write('%s<a name="call:%s" href="#flat:%s">%s</a>%s\n' % |
| (prefix, fname, fname, fname, suffix)) |
| else: |
| output.write('%s<a href="#call:%s">%s</a>%s\n' % |
| (prefix, fname, fname, suffix)) |
| for line in input: |
| for part in re.findall(r"(\w+(?:\.c)?|\W+)", line): |
| if part in labels: |
| part = '<a href="#call:%s">%s</a>' % (part, part) |
| output.write(part) |
| output.write(trailer) |
| output.close() |
| webbrowser.open("file:" + os.path.abspath(outputfilename)) |
| |
| if __name__ == '__main__': |
| main() |