Commit | Line | Data |
---|---|---|
1a00f590 RK |
1 | #! /usr/bin/env python |
2 | # | |
3 | # This file is part of DisOrder. | |
4 | # Copyright (C) 2007 Richard Kettlewell | |
5 | # | |
e7eb3a27 | 6 | # This program is free software: you can redistribute it and/or modify |
1a00f590 | 7 | # it under the terms of the GNU General Public License as published by |
e7eb3a27 | 8 | # the Free Software Foundation, either version 3 of the License, or |
1a00f590 | 9 | # (at your option) any later version. |
e7eb3a27 RK |
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 | # | |
1a00f590 | 16 | # You should have received a copy of the GNU General Public License |
e7eb3a27 | 17 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
1a00f590 RK |
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 | ||
43634380 RK |
34 | def line_count(f): |
35 | return len(open(f, "r").readlines()) | |
36 | ||
3d853cec | 37 | missing = {} |
1a00f590 RK |
38 | percent = {} |
39 | total_lines = 0 | |
40 | covered_lines = 0 | |
41 | args = sys.argv[1:] | |
42 | htmldir = None | |
3d853cec | 43 | while len(args) > 0 and re.match("^--", args[0]): |
1a00f590 RK |
44 | if args[0] == "--html": |
45 | htmldir = args[1] | |
46 | args = args[2:] | |
47 | else: | |
48 | fatal("unknown option '%s'" % args[0]) | |
3d853cec RK |
49 | for s in args: |
50 | missing[s] = True | |
1a00f590 RK |
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) | |
3d853cec RK |
58 | if name in missing: |
59 | del missing[name] | |
1a00f590 RK |
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 | ||
43634380 RK |
70 | for m in missing: |
71 | percent[m] = 0 | |
72 | total_lines += line_count(m) | |
73 | ||
1a00f590 RK |
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") | |
43634380 RK |
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"); | |
1a00f590 | 102 | index.write("<body><h1>gcov report</h1>\n") |
43634380 | 103 | index.write("<table><tr><th>File</th><th colspan=2>Coverage</th></tr>\n") |
1a00f590 | 104 | for k in keys: |
43634380 RK |
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])) | |
1a00f590 RK |
114 | index.write("</table>\n") |
115 | index.write("<p>Total coverage: %d%%</p>\n" % (100 * (covered_lines / total_lines))) | |
116 | for k in keys: | |
43634380 RK |
117 | if k in missing: |
118 | continue | |
1a00f590 RK |
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") |