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