chiark / gitweb /
Changes to HTML coverage output:
[disorder] / scripts / format-gcov-report
1 #! /usr/bin/env python
2 #
3 # This file is part of DisOrder.
4 # Copyright (C) 2007 Richard Kettlewell
5 #
6 # This program is free software: you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation, either version 3 of the License, or
9 # (at your option) any later version.
10
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 # GNU General Public License for more details.
15
16 # You should have received a copy of the GNU General Public License
17 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
18 #
19 import re,sys,os,string
20
21 def fatal(msg):
22   sys.stderr.write("%s\n" % msg)
23   sys.exit(1)
24
25 def sgmlquotechar(c):
26   if c == '&' or c == '<' or ord(c) < 32 or ord(c) > 126:
27     return "&#%d;" % ord(c)
28   else:
29     return c
30
31 def sgmlquote(s):
32   return string.join(map(sgmlquotechar, s),'')
33
34 def line_count(f):
35   return len(open(f, "r").readlines())
36
37 missing = {}
38 percent = {}
39 total_lines = 0
40 covered_lines = 0
41 args = sys.argv[1:]
42 htmldir = None
43 while len(args) > 0 and re.match("^--", args[0]):
44   if args[0] == "--html":
45     htmldir = args[1]
46     args = args[2:]
47   else:
48     fatal("unknown option '%s'" % args[0])
49 for s in args:
50   missing[s] = True
51
52 name = None
53 for line in sys.stdin:
54   line = line[:-1]
55   r = re.match("File ['`](?:.*/)?([^/]+.c)'", line)
56   if r:
57     name = r.group(1)
58     if name in missing:
59       del missing[name]
60   r = re.match("Lines executed:([0-9\\.]+)% of ([0-9]+)", line)
61   if r:
62     if name:
63       this_pc = float(r.group(1))
64       this_lines = int(r.group(2))
65       percent[name] = this_pc
66       total_lines += this_lines
67       covered_lines += this_lines * this_pc / 100.0
68     name = None
69
70 for m in missing:
71   percent[m] = 0
72   total_lines += line_count(m)
73
74 def cmp(a,b):
75   if percent[a] < percent[b]: return -1 
76   elif percent[a] > percent[b]: return 1
77   else: return 0
78
79 keys = percent.keys()
80 keys.sort(cmp)
81
82 if len(keys):
83   for k in keys:
84     print "%20s: %d%%" % (k, percent[k])
85   print "Total coverage: %d%%" % (100 * (covered_lines / total_lines))
86
87 if htmldir is not None and len(keys):
88   index = open(os.path.join(htmldir, "index.html"), "w")
89   index.write("<html><head><title>gcov report</title>\n")
90   index.write("<style type=\"text/css\">\n");
91   index.write(".missing {\n");
92   index.write("  color: red;\n");
93   index.write("}\n");
94   index.write(".bar {\n");
95   index.write("  width: 400px;\n");
96   index.write("}\n");
97   index.write(".bar div {\n");
98   index.write("  background-color: #00ff00;\n");
99   index.write("  height: 1em;\n");
100   index.write("}\n");
101   index.write("</style>\n");
102   index.write("<body><h1>gcov report</h1>\n")
103   index.write("<table><tr><th>File</th><th colspan=2>Coverage</th></tr>\n")
104   for k in keys:
105     index.write("<tr>\n")
106     if k in missing:
107       index.write("<td><span class=missing>%s</span>\n" % sgmlquote(k))
108     else:
109       index.write("<td><a href=\"%s.html\">%s</a>\n" %
110                   (sgmlquote(k), sgmlquote(k)))
111     index.write("<td>%d%%\n" % percent[k])
112     index.write("<td class=bar><div style=\"width: %d%%\"></div></td>\n"
113                 % int(percent[k]))
114   index.write("</table>\n")
115   index.write("<p>Total coverage: %d%%</p>\n" % (100 * (covered_lines / total_lines)))
116   for k in keys:
117     if k in missing:
118       continue
119     html = open(os.path.join(htmldir, "%s.html" % k), "w")
120     html.write("<html><head><title>%s</title>\n" % sgmlquote(k))
121     html.write("<body><h1>%s</h1>\n" % sgmlquote(k))
122     html.write("<pre>")
123     r = re.compile("^ *#####:.*")
124     for line in open("%s.gcov" % k, "r"):
125       if len(line) > 0 and line[-1] == '\n':
126         line = line[:-1]
127       if r.match(line):
128         html.write("<span style='background-color:#ffff00'>%s</span>\n" % sgmlquote(line))
129       else:
130         html.write("%s\n" % sgmlquote(line))
131     html.write("</pre>\n")