blob: b5a49f616fcb0ab4b0ef85a84fc8e502c5bfb317 [file] [log] [blame]
Marco Nelissen594375d2009-07-14 09:04:04 -07001#!/usr/bin/env python
Marco Nelissen8e201962010-03-10 16:16:02 -08002# This file uses the following encoding: utf-8
Marco Nelissen594375d2009-07-14 09:04:04 -07003
Anthony Kingc713d762015-11-03 00:23:11 +00004from __future__ import print_function
5
Marco Nelissen594375d2009-07-14 09:04:04 -07006import sys
7import re
8
9if len(sys.argv) == 1:
Anthony Kingc713d762015-11-03 00:23:11 +000010 print('usage: ' + sys.argv[0] + ' <build.log>')
Marco Nelissen594375d2009-07-14 09:04:04 -070011 sys.exit()
12
13# if you add another level, don't forget to give it a color below
14class severity:
15 UNKNOWN=0
16 SKIP=100
17 FIXMENOW=1
18 HIGH=2
19 MEDIUM=3
20 LOW=4
21 HARMLESS=5
22
23def colorforseverity(sev):
24 if sev == severity.FIXMENOW:
25 return 'fuchsia'
26 if sev == severity.HIGH:
27 return 'red'
28 if sev == severity.MEDIUM:
29 return 'orange'
30 if sev == severity.LOW:
31 return 'yellow'
32 if sev == severity.HARMLESS:
33 return 'limegreen'
34 if sev == severity.UNKNOWN:
35 return 'blue'
36 return 'grey'
37
38warnpatterns = [
39 { 'category':'make', 'severity':severity.MEDIUM, 'members':[], 'option':'',
40 'description':'make: overriding commands/ignoring old commands',
41 'patterns':[r".*: warning: overriding commands for target .+",
42 r".*: warning: ignoring old commands for target .+"] },
43 { 'category':'C/C++', 'severity':severity.HIGH, 'members':[], 'option':'-Wimplicit-function-declaration',
44 'description':'Implicit function declaration',
45 'patterns':[r".*: warning: implicit declaration of function .+"] },
46 { 'category':'C/C++', 'severity':severity.SKIP, 'members':[], 'option':'',
47 'description':'',
48 'patterns':[r".*: warning: conflicting types for '.+'"] },
49 { 'category':'C/C++', 'severity':severity.HIGH, 'members':[], 'option':'-Wtype-limits',
50 'description':'Expression always evaluates to true or false',
51 'patterns':[r".*: warning: comparison is always false due to limited range of data type",
52 r".*: warning: comparison of unsigned expression >= 0 is always true",
53 r".*: warning: comparison of unsigned expression < 0 is always false"] },
54 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'',
55 'description':'Incompatible pointer types',
56 'patterns':[r".*: warning: assignment from incompatible pointer type",
Marco Nelissen8e201962010-03-10 16:16:02 -080057 r".*: warning: return from incompatible pointer type",
Marco Nelissen594375d2009-07-14 09:04:04 -070058 r".*: warning: passing argument [0-9]+ of '.*' from incompatible pointer type",
59 r".*: warning: initialization from incompatible pointer type"] },
60 { 'category':'C/C++', 'severity':severity.HIGH, 'members':[], 'option':'-fno-builtin',
61 'description':'Incompatible declaration of built in function',
62 'patterns':[r".*: warning: incompatible implicit declaration of built-in function .+"] },
63 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wunused-parameter',
64 'description':'Unused parameter',
65 'patterns':[r".*: warning: unused parameter '.*'"] },
66 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wunused',
67 'description':'Unused function, variable or label',
Marco Nelissen8e201962010-03-10 16:16:02 -080068 'patterns':[r".*: warning: '.+' defined but not used",
69 r".*: warning: unused variable '.+'"] },
Marco Nelissen594375d2009-07-14 09:04:04 -070070 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wunused-value',
71 'description':'Statement with no effect',
72 'patterns':[r".*: warning: statement with no effect"] },
73 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wmissing-field-initializers',
74 'description':'Missing initializer',
75 'patterns':[r".*: warning: missing initializer"] },
76 { 'category':'cont.', 'severity':severity.SKIP, 'members':[], 'option':'',
77 'description':'',
78 'patterns':[r".*: warning: \(near initialization for '.+'\)"] },
79 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wformat',
80 'description':'Format string does not match arguments',
81 'patterns':[r".*: warning: format '.+' expects type '.+', but argument [0-9]+ has type '.+'"] },
82 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wformat-extra-args',
83 'description':'Too many arguments for format string',
84 'patterns':[r".*: warning: too many arguments for format"] },
85 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wsign-compare',
86 'description':'Comparison between signed and unsigned',
87 'patterns':[r".*: warning: comparison between signed and unsigned",
88 r".*: warning: comparison of promoted \~unsigned with unsigned",
89 r".*: warning: signed and unsigned type in conditional expression"] },
Marco Nelissen8e201962010-03-10 16:16:02 -080090 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'',
91 'description':'Comparison between enum and non-enum',
92 'patterns':[r".*: warning: enumeral and non-enumeral type in conditional expression"] },
Marco Nelissen594375d2009-07-14 09:04:04 -070093 { 'category':'libpng', 'severity':severity.MEDIUM, 'members':[], 'option':'',
94 'description':'libpng: zero area',
95 'patterns':[r".*libpng warning: Ignoring attempt to set cHRM RGB triangle with zero area"] },
96 { 'category':'aapt', 'severity':severity.MEDIUM, 'members':[], 'option':'',
97 'description':'aapt: no comment for public symbol',
98 'patterns':[r".*: warning: No comment for public symbol .+"] },
99 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wmissing-braces',
100 'description':'Missing braces around initializer',
101 'patterns':[r".*: warning: missing braces around initializer.*"] },
102 { 'category':'C/C++', 'severity':severity.HARMLESS, 'members':[], 'option':'',
103 'description':'No newline at end of file',
104 'patterns':[r".*: warning: no newline at end of file"] },
105 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wcast-qual',
106 'description':'Qualifier discarded',
107 'patterns':[r".*: warning: passing argument [0-9]+ of '.+' discards qualifiers from pointer target type",
108 r".*: warning: assignment discards qualifiers from pointer target type",
109 r".*: warning: return discards qualifiers from pointer target type"] },
110 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wattributes',
111 'description':'Attribute ignored',
112 'patterns':[r".*: warning: '_*packed_*' attribute ignored"] },
113 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wattributes',
114 'description':'Visibility mismatch',
115 'patterns':[r".*: warning: '.+' declared with greater visibility than the type of its field '.+'"] },
116 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'',
117 'description':'Shift count greater than width of type',
118 'patterns':[r".*: warning: (left|right) shift count >= width of type"] },
119 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'',
120 'description':'extern &lt;foo&gt; is initialized',
121 'patterns':[r".*: warning: '.+' initialized and declared 'extern'"] },
122 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wold-style-declaration',
123 'description':'Old style declaration',
124 'patterns':[r".*: warning: 'static' is not at beginning of declaration"] },
125 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wuninitialized',
126 'description':'Variable may be used uninitialized',
127 'patterns':[r".*: warning: '.+' may be used uninitialized in this function"] },
128 { 'category':'C/C++', 'severity':severity.HIGH, 'members':[], 'option':'-Wuninitialized',
129 'description':'Variable is used uninitialized',
130 'patterns':[r".*: warning: '.+' is used uninitialized in this function"] },
131 { 'category':'ld', 'severity':severity.MEDIUM, 'members':[], 'option':'-fshort-enums',
132 'description':'ld: possible enum size mismatch',
133 'patterns':[r".*: warning: .* uses variable-size enums yet the output is to use 32-bit enums; use of enum values across objects may fail"] },
134 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wpointer-sign',
135 'description':'Pointer targets differ in signedness',
136 'patterns':[r".*: warning: pointer targets in initialization differ in signedness",
137 r".*: warning: pointer targets in assignment differ in signedness",
138 r".*: warning: pointer targets in return differ in signedness",
139 r".*: warning: pointer targets in passing argument [0-9]+ of '.+' differ in signedness"] },
140 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wstrict-overflow',
141 'description':'Assuming overflow does not occur',
142 'patterns':[r".*: warning: assuming signed overflow does not occur when assuming that .* is always (true|false)"] },
143 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wempty-body',
144 'description':'Suggest adding braces around empty body',
145 'patterns':[r".*: warning: suggest braces around empty body in an 'if' statement",
146 r".*: warning: empty body in an if-statement",
147 r".*: warning: suggest braces around empty body in an 'else' statement",
148 r".*: warning: empty body in an else-statement"] },
149 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wparentheses',
150 'description':'Suggest adding parentheses',
151 'patterns':[r".*: warning: suggest explicit braces to avoid ambiguous 'else'",
152 r".*: warning: suggest parentheses around arithmetic in operand of '.+'",
153 r".*: warning: suggest parentheses around comparison in operand of '.+'",
154 r".*: warning: suggest parentheses around '.+?' .+ '.+?'",
155 r".*: warning: suggest parentheses around assignment used as truth value"] },
156 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'',
157 'description':'Static variable used in non-static inline function',
158 'patterns':[r".*: warning: '.+' is static but used in inline function '.+' which is not static"] },
159 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wimplicit int',
160 'description':'No type or storage class (will default to int)',
161 'patterns':[r".*: warning: data definition has no type or storage class"] },
162 { 'category':'cont.', 'severity':severity.SKIP, 'members':[], 'option':'',
163 'description':'',
164 'patterns':[r".*: warning: type defaults to 'int' in declaration of '.+'"] },
165 { 'category':'cont.', 'severity':severity.SKIP, 'members':[], 'option':'',
166 'description':'',
167 'patterns':[r".*: warning: parameter names \(without types\) in function declaration"] },
168 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wstrict-aliasing',
169 'description':'Dereferencing &lt;foo&gt; breaks strict aliasing rules',
170 'patterns':[r".*: warning: dereferencing .* break strict-aliasing rules"] },
171 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wpointer-to-int-cast',
172 'description':'Cast from pointer to integer of different size',
173 'patterns':[r".*: warning: cast from pointer to integer of different size"] },
174 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wint-to-pointer-cast',
175 'description':'Cast to pointer from integer of different size',
176 'patterns':[r".*: warning: cast to pointer from integer of different size"] },
177 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'',
178 'description':'Symbol redefined',
179 'patterns':[r".*: warning: "".+"" redefined"] },
180 { 'category':'cont.', 'severity':severity.SKIP, 'members':[], 'option':'',
181 'description':'',
182 'patterns':[r".*: warning: this is the location of the previous definition"] },
183 { 'category':'ld', 'severity':severity.MEDIUM, 'members':[], 'option':'',
184 'description':'ld: type and size of dynamic symbol are not defined',
185 'patterns':[r".*: warning: type and size of dynamic symbol `.+' are not defined"] },
186 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'',
187 'description':'Pointer from integer without cast',
188 'patterns':[r".*: warning: assignment makes pointer from integer without a cast"] },
189 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'',
190 'description':'Pointer from integer without cast',
191 'patterns':[r".*: warning: passing argument [0-9]+ of '.+' makes pointer from integer without a cast"] },
192 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'',
193 'description':'Integer from pointer without cast',
194 'patterns':[r".*: warning: assignment makes integer from pointer without a cast"] },
195 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'',
196 'description':'Integer from pointer without cast',
197 'patterns':[r".*: warning: passing argument [0-9]+ of '.+' makes integer from pointer without a cast"] },
198 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'',
199 'description':'Integer from pointer without cast',
200 'patterns':[r".*: warning: return makes integer from pointer without a cast"] },
201 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wunknown-pragmas',
202 'description':'Ignoring pragma',
203 'patterns':[r".*: warning: ignoring #pragma .+"] },
204 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wclobbered',
205 'description':'Variable might be clobbered by longjmp or vfork',
206 'patterns':[r".*: warning: variable '.+' might be clobbered by 'longjmp' or 'vfork'"] },
207 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wclobbered',
208 'description':'Argument might be clobbered by longjmp or vfork',
209 'patterns':[r".*: warning: argument '.+' might be clobbered by 'longjmp' or 'vfork'"] },
210 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wredundant-decls',
211 'description':'Redundant declaration',
212 'patterns':[r".*: warning: redundant redeclaration of '.+'"] },
213 { 'category':'cont.', 'severity':severity.SKIP, 'members':[], 'option':'',
214 'description':'',
215 'patterns':[r".*: warning: previous declaration of '.+' was here"] },
216 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wswitch-enum',
217 'description':'Enum value not handled in switch',
218 'patterns':[r".*: warning: enumeration value '.+' not handled in switch"] },
219 { 'category':'java', 'severity':severity.MEDIUM, 'members':[], 'option':'-encoding',
220 'description':'Java: Non-ascii characters used, but ascii encoding specified',
221 'patterns':[r".*: warning: unmappable character for encoding ascii"] },
222 { 'category':'java', 'severity':severity.MEDIUM, 'members':[], 'option':'',
223 'description':'Java: Non-varargs call of varargs method with inexact argument type for last parameter',
224 'patterns':[r".*: warning: non-varargs call of varargs method with inexact argument type for last parameter"] },
225 { 'category':'aapt', 'severity':severity.MEDIUM, 'members':[], 'option':'',
Marco Nelissen8e201962010-03-10 16:16:02 -0800226 'description':'aapt: No default translation',
227 'patterns':[r".*: warning: string '.+' has no default translation in .*"] },
228 { 'category':'aapt', 'severity':severity.MEDIUM, 'members':[], 'option':'',
229 'description':'aapt: Missing default or required localization',
230 'patterns':[r".*: warning: \*\*\*\* string '.+' has no default or required localization for '.+' in .+"] },
231 { 'category':'aapt', 'severity':severity.MEDIUM, 'members':[], 'option':'',
Marco Nelissen594375d2009-07-14 09:04:04 -0700232 'description':'aapt: String marked untranslatable, but translation exists',
233 'patterns':[r".*: warning: string '.+' in .* marked untranslatable but exists in locale '??_??'"] },
234 { 'category':'aapt', 'severity':severity.MEDIUM, 'members':[], 'option':'',
235 'description':'aapt: empty span in string',
236 'patterns':[r".*: warning: empty '.+' span found in text '.+"] },
237 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'',
238 'description':'Taking address of temporary',
239 'patterns':[r".*: warning: taking address of temporary"] },
240 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'',
241 'description':'Possible broken line continuation',
242 'patterns':[r".*: warning: backslash and newline separated by space"] },
243 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Warray-bounds',
244 'description':'Array subscript out of bounds',
Marco Nelissen8e201962010-03-10 16:16:02 -0800245 'patterns':[r".*: warning: array subscript is above array bounds",
246 r".*: warning: array subscript is below array bounds"] },
Marco Nelissen594375d2009-07-14 09:04:04 -0700247 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'',
248 'description':'Decimal constant is unsigned only in ISO C90',
249 'patterns':[r".*: warning: this decimal constant is unsigned only in ISO C90"] },
250 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wmain',
251 'description':'main is usually a function',
252 'patterns':[r".*: warning: 'main' is usually a function"] },
253 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'',
254 'description':'Typedef ignored',
255 'patterns':[r".*: warning: 'typedef' was ignored in this declaration"] },
256 { 'category':'C/C++', 'severity':severity.HIGH, 'members':[], 'option':'-Waddress',
257 'description':'Address always evaluates to true',
258 'patterns':[r".*: warning: the address of '.+' will always evaluate as 'true'"] },
259 { 'category':'C/C++', 'severity':severity.FIXMENOW, 'members':[], 'option':'',
260 'description':'Freeing a non-heap object',
261 'patterns':[r".*: warning: attempt to free a non-heap object '.+'"] },
262 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wchar-subscripts',
263 'description':'Array subscript has type char',
264 'patterns':[r".*: warning: array subscript has type 'char'"] },
265 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'',
266 'description':'Constant too large for type',
267 'patterns':[r".*: warning: integer constant is too large for '.+' type"] },
268 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Woverflow',
269 'description':'Constant too large for type, truncated',
270 'patterns':[r".*: warning: large integer implicitly truncated to unsigned type"] },
271 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Woverflow',
272 'description':'Overflow in implicit constant conversion',
273 'patterns':[r".*: warning: overflow in implicit constant conversion"] },
274 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'',
275 'description':'Declaration does not declare anything',
276 'patterns':[r".*: warning: declaration 'class .+' does not declare anything"] },
277 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wreorder',
278 'description':'Initialization order will be different',
279 'patterns':[r".*: warning: '.+' will be initialized after"] },
280 { 'category':'cont.', 'severity':severity.SKIP, 'members':[], 'option':'',
281 'description':'',
282 'patterns':[r".*: warning: '.+'"] },
283 { 'category':'cont.', 'severity':severity.SKIP, 'members':[], 'option':'',
284 'description':'',
Marco Nelissen8e201962010-03-10 16:16:02 -0800285 'patterns':[r".*: warning: base '.+'"] },
286 { 'category':'cont.', 'severity':severity.SKIP, 'members':[], 'option':'',
287 'description':'',
Marco Nelissen594375d2009-07-14 09:04:04 -0700288 'patterns':[r".*: warning: when initialized here"] },
289 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wmissing-parameter-type',
290 'description':'Parameter type not specified',
291 'patterns':[r".*: warning: type of '.+' defaults to 'int'"] },
292 { 'category':'gcc', 'severity':severity.MEDIUM, 'members':[], 'option':'',
293 'description':'Invalid option for C file',
294 'patterns':[r".*: warning: command line option "".+"" is valid for C\+\+\/ObjC\+\+ but not for C"] },
295 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'',
296 'description':'User warning',
297 'patterns':[r".*: warning: #warning "".+"""] },
298 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wextra',
299 'description':'Dereferencing void*',
300 'patterns':[r".*: warning: dereferencing 'void \*' pointer"] },
301 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wextra',
302 'description':'Comparison of pointer to zero',
303 'patterns':[r".*: warning: ordered comparison of pointer with integer zero"] },
304 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wwrite-strings',
305 'description':'Conversion of string constant to non-const char*',
306 'patterns':[r".*: warning: deprecated conversion from string constant to '.+'"] },
307 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wstrict-prototypes',
308 'description':'Function declaration isn''t a prototype',
309 'patterns':[r".*: warning: function declaration isn't a prototype"] },
310 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wignored-qualifiers',
311 'description':'Type qualifiers ignored on function return value',
312 'patterns':[r".*: warning: type qualifiers ignored on function return type"] },
313 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'',
314 'description':'&lt;foo&gt; declared inside parameter list, scope limited to this definition',
315 'patterns':[r".*: warning: '.+' declared inside parameter list"] },
316 { 'category':'cont.', 'severity':severity.SKIP, 'members':[], 'option':'',
317 'description':'',
318 'patterns':[r".*: warning: its scope is only this definition or declaration, which is probably not what you want"] },
319 { 'category':'C/C++', 'severity':severity.LOW, 'members':[], 'option':'-Wcomment',
320 'description':'Line continuation inside comment',
321 'patterns':[r".*: warning: multi-line comment"] },
Marco Nelissen8e201962010-03-10 16:16:02 -0800322 { 'category':'C/C++', 'severity':severity.LOW, 'members':[], 'option':'-Wcomment',
323 'description':'Comment inside comment',
324 'patterns':[r".*: warning: "".+"" within comment"] },
Marco Nelissen594375d2009-07-14 09:04:04 -0700325 { 'category':'C/C++', 'severity':severity.HARMLESS, 'members':[], 'option':'',
326 'description':'Extra tokens after #endif',
327 'patterns':[r".*: warning: extra tokens at end of #endif directive"] },
328 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wenum-compare',
329 'description':'Comparison between different enums',
330 'patterns':[r".*: warning: comparison between 'enum .+' and 'enum .+'"] },
331 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wconversion',
332 'description':'Implicit conversion of negative number to unsigned type',
333 'patterns':[r".*: warning: converting negative value '.+' to '.+'"] },
334 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'',
335 'description':'Passing NULL as non-pointer argument',
Marco Nelissen5236fbd2009-07-31 08:30:34 -0700336 'patterns':[r".*: warning: passing NULL to non-pointer argument [0-9]+ of '.+'"] },
Marco Nelissen594375d2009-07-14 09:04:04 -0700337 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wctor-dtor-privacy',
338 'description':'Class seems unusable because of private ctor/dtor' ,
339 'patterns':[r".*: warning: all member functions in class '.+' are private"] },
340 # skip this next one, because it only points out some RefBase-based classes where having a private destructor is perfectly fine
341 { 'category':'C/C++', 'severity':severity.SKIP, 'members':[], 'option':'-Wctor-dtor-privacy',
342 'description':'Class seems unusable because of private ctor/dtor' ,
343 'patterns':[r".*: warning: 'class .+' only defines a private destructor and has no friends"] },
344 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wctor-dtor-privacy',
345 'description':'Class seems unusable because of private ctor/dtor' ,
346 'patterns':[r".*: warning: 'class .+' only defines private constructors and has no friends"] },
347 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wpointer-arith',
348 'description':'void* used in arithmetic' ,
349 'patterns':[r".*: warning: pointer of type 'void \*' used in (arithmetic|subtraction)",
350 r".*: warning: wrong type argument to increment"] },
351 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wsign-promo',
352 'description':'Overload resolution chose to promote from unsigned or enum to signed type' ,
353 'patterns':[r".*: warning: passing '.+' chooses 'int' over '.* int'"] },
354 { 'category':'cont.', 'severity':severity.SKIP, 'members':[], 'option':'',
355 'description':'',
356 'patterns':[r".*: warning: in call to '.+'"] },
Marco Nelissen5236fbd2009-07-31 08:30:34 -0700357 { 'category':'C/C++', 'severity':severity.HIGH, 'members':[], 'option':'-Wextra',
358 'description':'Base should be explicitly initialized in copy constructor',
359 'patterns':[r".*: warning: base class '.+' should be explicitly initialized in the copy constructor"] },
360 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'',
361 'description':'Converting from <type> to <other type>',
362 'patterns':[r".*: warning: converting to '.+' from '.+'"] },
Marco Nelissen8e201962010-03-10 16:16:02 -0800363 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'',
364 'description':'Return value from void function',
365 'patterns':[r".*: warning: 'return' with a value, in function returning void"] },
366 { 'category':'C/C++', 'severity':severity.LOW, 'members':[], 'option':'',
367 'description':'Useless specifier',
368 'patterns':[r".*: warning: useless storage class specifier in empty declaration"] },
369 { 'category':'logtags', 'severity':severity.LOW, 'members':[], 'option':'',
370 'description':'Duplicate logtag',
371 'patterns':[r".*: warning: tag "".+"" \(None\) duplicated in .+"] },
372 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'',
373 'description':'Operator new returns NULL',
374 'patterns':[r".*: warning: 'operator new' must not return NULL unless it is declared 'throw\(\)' .+"] },
375 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'',
376 'description':'NULL used in arithmetic',
377 'patterns':[r".*: warning: NULL used in arithmetic"] },
378 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'',
379 'description':'Use of deprecated method',
380 'patterns':[r".*: warning: '.+' is deprecated .+"] },
Marco Nelissen594375d2009-07-14 09:04:04 -0700381
382 # these next ones are to deal with formatting problems resulting from the log being mixed up by 'make -j'
383 { 'category':'C/C++', 'severity':severity.SKIP, 'members':[], 'option':'',
384 'description':'',
385 'patterns':[r".*: warning: ,$"] },
386 { 'category':'C/C++', 'severity':severity.SKIP, 'members':[], 'option':'',
387 'description':'',
388 'patterns':[r".*: warning: $"] },
389 { 'category':'C/C++', 'severity':severity.SKIP, 'members':[], 'option':'',
390 'description':'',
391 'patterns':[r".*: warning: In file included from .+,"] },
392
393 # catch-all for warnings this script doesn't know about yet
394 { 'category':'C/C++', 'severity':severity.UNKNOWN, 'members':[], 'option':'',
395 'description':'Unclassified/unrecognized warnings',
396 'patterns':[r".*: warning: .+"] },
397]
398
399anchor = 0
400cur_row_color = 0
401row_colors = [ 'e0e0e0', 'd0d0d0' ]
402
403def output(text):
Anthony Kingc713d762015-11-03 00:23:11 +0000404 print(text, end=' ')
Marco Nelissen594375d2009-07-14 09:04:04 -0700405
406def htmlbig(param):
407 return '<font size="+2">' + param + '</font>'
408
409def dumphtmlprologue(title):
410 output('<html>\n<head>\n<title>' + title + '</title>\n<body>\n')
411 output(htmlbig(title))
412 output('<p>\n')
413
414def tablerow(text):
415 global cur_row_color
416 output('<tr bgcolor="' + row_colors[cur_row_color] + '"><td colspan="2">',)
417 cur_row_color = 1 - cur_row_color
418 output(text,)
419 output('</td></tr>')
420
421def begintable(text, backgroundcolor):
422 global anchor
423 output('<table border="1" rules="cols" frame="box" width="100%" bgcolor="black"><tr bgcolor="' +
424 backgroundcolor + '"><a name="anchor' + str(anchor) + '"><td>')
425 output(htmlbig(text[0]) + '<br>')
426 for i in text[1:]:
427 output(i + '<br>')
428 output('</td>')
429 output('<td width="100" bgcolor="grey"><a align="right" href="#anchor' + str(anchor-1) +
430 '">previous</a><br><a align="right" href="#anchor' + str(anchor+1) + '">next</a>')
431 output('</td></a></tr>')
432 anchor += 1
433
434def endtable():
435 output('</table><p>')
436
437
438# dump some stats about total number of warnings and such
439def dumpstats():
440 known = 0
441 unknown = 0
442 for i in warnpatterns:
443 if i['severity'] == severity.UNKNOWN:
444 unknown += len(i['members'])
445 elif i['severity'] != severity.SKIP:
446 known += len(i['members'])
447 output('Number of classified warnings: <b>' + str(known) + '</b><br>' )
448 output('Number of unclassified warnings: <b>' + str(unknown) + '</b><br>')
449 total = unknown + known
450 output('Total number of warnings: <b>' + str(total) + '</b>')
451 if total < 1000:
452 output('(low count may indicate incremental build)')
453 output('<p>')
454
455def allpatterns(cat):
456 pats = ''
457 for i in cat['patterns']:
458 pats += i
459 pats += ' / '
460 return pats
461
462def descriptionfor(cat):
463 if cat['description'] != '':
464 return cat['description']
465 return allpatterns(cat)
466
467
468# show which warnings no longer occur
469def dumpfixed():
470 tablestarted = False
471 for i in warnpatterns:
472 if len(i['members']) == 0 and i['severity'] != severity.SKIP:
473 if tablestarted == False:
474 tablestarted = True
475 begintable(['Fixed warnings', 'No more occurences. Please consider turning these in to errors if possible, before they are reintroduced in to the build'], 'blue')
476 tablerow(i['description'] + ' (' + allpatterns(i) + ') ' + i['option'])
477 if tablestarted:
478 endtable()
479
480
481# dump a category, provided it is not marked as 'SKIP' and has more than 0 occurrences
482def dumpcategory(cat):
483 if cat['severity'] != severity.SKIP and len(cat['members']) != 0:
484 header = [descriptionfor(cat),str(len(cat['members'])) + ' occurences:']
485 if cat['option'] != '':
486 header[1:1] = [' (related option: ' + cat['option'] +')']
487 begintable(header, colorforseverity(cat['severity']))
488 for i in cat['members']:
489 tablerow(i)
490 endtable()
491
492
493# dump everything for a given severity
494def dumpseverity(sev):
495 for i in warnpatterns:
496 if i['severity'] == sev:
497 dumpcategory(i)
498
499
500def classifywarning(line):
501 for i in warnpatterns:
Marco Nelissen2bdc7ec2009-09-29 10:19:29 -0700502 for cpat in i['compiledpatterns']:
503 if cpat.match(line):
Marco Nelissen594375d2009-07-14 09:04:04 -0700504 i['members'].append(line)
505 return
506 else:
507 # If we end up here, there was a problem parsing the log
508 # probably caused by 'make -j' mixing the output from
509 # 2 or more concurrent compiles
510 pass
511
Marco Nelissen2bdc7ec2009-09-29 10:19:29 -0700512# precompiling every pattern speeds up parsing by about 30x
513def compilepatterns():
514 for i in warnpatterns:
515 i['compiledpatterns'] = []
516 for pat in i['patterns']:
517 i['compiledpatterns'].append(re.compile(pat))
Marco Nelissen594375d2009-07-14 09:04:04 -0700518
519infile = open(sys.argv[1], 'r')
520warnings = []
521
522platformversion = 'unknown'
523targetproduct = 'unknown'
524targetvariant = 'unknown'
525linecounter = 0
526
527warningpattern = re.compile('.* warning:.*')
Marco Nelissen2bdc7ec2009-09-29 10:19:29 -0700528compilepatterns()
Marco Nelissen594375d2009-07-14 09:04:04 -0700529
530# read the log file and classify all the warnings
531lastmatchedline = ''
532for line in infile:
Marco Nelissen8e201962010-03-10 16:16:02 -0800533 # replace fancy quotes with plain ol' quotes
534 line = line.replace("‘", "'");
535 line = line.replace("’", "'");
Marco Nelissen594375d2009-07-14 09:04:04 -0700536 if warningpattern.match(line):
537 if line != lastmatchedline:
538 classifywarning(line)
539 lastmatchedline = line
540 else:
541 # save a little bit of time by only doing this for the first few lines
542 if linecounter < 50:
543 linecounter +=1
544 m = re.search('(?<=^PLATFORM_VERSION=).*', line)
545 if m != None:
546 platformversion = m.group(0)
547 m = re.search('(?<=^TARGET_PRODUCT=).*', line)
548 if m != None:
549 targetproduct = m.group(0)
550 m = re.search('(?<=^TARGET_BUILD_VARIANT=).*', line)
551 if m != None:
552 targetvariant = m.group(0)
553
554
555# dump the html output to stdout
556dumphtmlprologue('Warnings for ' + platformversion + ' - ' + targetproduct + ' - ' + targetvariant)
557dumpstats()
558dumpseverity(severity.FIXMENOW)
559dumpseverity(severity.HIGH)
560dumpseverity(severity.MEDIUM)
561dumpseverity(severity.LOW)
562dumpseverity(severity.HARMLESS)
563dumpseverity(severity.UNKNOWN)
564dumpfixed()
565