diff options
author | Marco Nelissen <marcone@google.com> | 2009-07-14 09:04:04 -0700 |
---|---|---|
committer | Marco Nelissen <marcone@google.com> | 2009-07-14 12:22:29 -0700 |
commit | 594375db5f1eb4576fec7f6fb37e7a322a5d848b (patch) | |
tree | 9a81d8ea1ada4f467b14bf289d37c259050318df | |
parent | e4aaa368b3c58c72a771c23de81e46b729bc736c (diff) | |
download | build-594375db5f1eb4576fec7f6fb37e7a322a5d848b.zip build-594375db5f1eb4576fec7f6fb37e7a322a5d848b.tar.gz build-594375db5f1eb4576fec7f6fb37e7a322a5d848b.tar.bz2 |
Python script to parse a build log and present the warnings in html
-rwxr-xr-x | tools/warn.py | 515 |
1 files changed, 515 insertions, 0 deletions
diff --git a/tools/warn.py b/tools/warn.py new file mode 100755 index 0000000..7930299 --- /dev/null +++ b/tools/warn.py @@ -0,0 +1,515 @@ +#!/usr/bin/env python + +import sys +import re + +if len(sys.argv) == 1: + print 'usage: ' + sys.argv[0] + ' <build.log>' + sys.exit() + +# if you add another level, don't forget to give it a color below +class severity: + UNKNOWN=0 + SKIP=100 + FIXMENOW=1 + HIGH=2 + MEDIUM=3 + LOW=4 + HARMLESS=5 + +def colorforseverity(sev): + if sev == severity.FIXMENOW: + return 'fuchsia' + if sev == severity.HIGH: + return 'red' + if sev == severity.MEDIUM: + return 'orange' + if sev == severity.LOW: + return 'yellow' + if sev == severity.HARMLESS: + return 'limegreen' + if sev == severity.UNKNOWN: + return 'blue' + return 'grey' + +warnpatterns = [ + { 'category':'make', 'severity':severity.MEDIUM, 'members':[], 'option':'', + 'description':'make: overriding commands/ignoring old commands', + 'patterns':[r".*: warning: overriding commands for target .+", + r".*: warning: ignoring old commands for target .+"] }, + { 'category':'C/C++', 'severity':severity.HIGH, 'members':[], 'option':'-Wimplicit-function-declaration', + 'description':'Implicit function declaration', + 'patterns':[r".*: warning: implicit declaration of function .+"] }, + { 'category':'C/C++', 'severity':severity.SKIP, 'members':[], 'option':'', + 'description':'', + 'patterns':[r".*: warning: conflicting types for '.+'"] }, + { 'category':'C/C++', 'severity':severity.HIGH, 'members':[], 'option':'-Wtype-limits', + 'description':'Expression always evaluates to true or false', + 'patterns':[r".*: warning: comparison is always false due to limited range of data type", + r".*: warning: comparison of unsigned expression >= 0 is always true", + r".*: warning: comparison of unsigned expression < 0 is always false"] }, + { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'', + 'description':'Incompatible pointer types', + 'patterns':[r".*: warning: assignment from incompatible pointer type", + r".*: warning: passing argument [0-9]+ of '.*' from incompatible pointer type", + r".*: warning: initialization from incompatible pointer type"] }, + { 'category':'C/C++', 'severity':severity.HIGH, 'members':[], 'option':'-fno-builtin', + 'description':'Incompatible declaration of built in function', + 'patterns':[r".*: warning: incompatible implicit declaration of built-in function .+"] }, + { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wunused-parameter', + 'description':'Unused parameter', + 'patterns':[r".*: warning: unused parameter '.*'"] }, + { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wunused', + 'description':'Unused function, variable or label', + 'patterns':[r".*: warning: '.+' defined but not used"] }, + { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wunused-value', + 'description':'Statement with no effect', + 'patterns':[r".*: warning: statement with no effect"] }, + { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wmissing-field-initializers', + 'description':'Missing initializer', + 'patterns':[r".*: warning: missing initializer"] }, + { 'category':'cont.', 'severity':severity.SKIP, 'members':[], 'option':'', + 'description':'', + 'patterns':[r".*: warning: \(near initialization for '.+'\)"] }, + { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wformat', + 'description':'Format string does not match arguments', + 'patterns':[r".*: warning: format '.+' expects type '.+', but argument [0-9]+ has type '.+'"] }, + { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wformat-extra-args', + 'description':'Too many arguments for format string', + 'patterns':[r".*: warning: too many arguments for format"] }, + { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wsign-compare', + 'description':'Comparison between signed and unsigned', + 'patterns':[r".*: warning: comparison between signed and unsigned", + r".*: warning: comparison of promoted \~unsigned with unsigned", + r".*: warning: signed and unsigned type in conditional expression"] }, + { 'category':'libpng', 'severity':severity.MEDIUM, 'members':[], 'option':'', + 'description':'libpng: zero area', + 'patterns':[r".*libpng warning: Ignoring attempt to set cHRM RGB triangle with zero area"] }, + { 'category':'aapt', 'severity':severity.MEDIUM, 'members':[], 'option':'', + 'description':'aapt: no comment for public symbol', + 'patterns':[r".*: warning: No comment for public symbol .+"] }, + { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wmissing-braces', + 'description':'Missing braces around initializer', + 'patterns':[r".*: warning: missing braces around initializer.*"] }, + { 'category':'C/C++', 'severity':severity.HARMLESS, 'members':[], 'option':'', + 'description':'No newline at end of file', + 'patterns':[r".*: warning: no newline at end of file"] }, + { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wcast-qual', + 'description':'Qualifier discarded', + 'patterns':[r".*: warning: passing argument [0-9]+ of '.+' discards qualifiers from pointer target type", + r".*: warning: assignment discards qualifiers from pointer target type", + r".*: warning: return discards qualifiers from pointer target type"] }, + { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wattributes', + 'description':'Attribute ignored', + 'patterns':[r".*: warning: '_*packed_*' attribute ignored"] }, + { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wattributes', + 'description':'Visibility mismatch', + 'patterns':[r".*: warning: '.+' declared with greater visibility than the type of its field '.+'"] }, + { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'', + 'description':'Shift count greater than width of type', + 'patterns':[r".*: warning: (left|right) shift count >= width of type"] }, + { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'', + 'description':'extern <foo> is initialized', + 'patterns':[r".*: warning: '.+' initialized and declared 'extern'"] }, + { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wold-style-declaration', + 'description':'Old style declaration', + 'patterns':[r".*: warning: 'static' is not at beginning of declaration"] }, + { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wuninitialized', + 'description':'Variable may be used uninitialized', + 'patterns':[r".*: warning: '.+' may be used uninitialized in this function"] }, + { 'category':'C/C++', 'severity':severity.HIGH, 'members':[], 'option':'-Wuninitialized', + 'description':'Variable is used uninitialized', + 'patterns':[r".*: warning: '.+' is used uninitialized in this function"] }, + { 'category':'ld', 'severity':severity.MEDIUM, 'members':[], 'option':'-fshort-enums', + 'description':'ld: possible enum size mismatch', + 'patterns':[r".*: warning: .* uses variable-size enums yet the output is to use 32-bit enums; use of enum values across objects may fail"] }, + { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wpointer-sign', + 'description':'Pointer targets differ in signedness', + 'patterns':[r".*: warning: pointer targets in initialization differ in signedness", + r".*: warning: pointer targets in assignment differ in signedness", + r".*: warning: pointer targets in return differ in signedness", + r".*: warning: pointer targets in passing argument [0-9]+ of '.+' differ in signedness"] }, + { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wstrict-overflow', + 'description':'Assuming overflow does not occur', + 'patterns':[r".*: warning: assuming signed overflow does not occur when assuming that .* is always (true|false)"] }, + { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wempty-body', + 'description':'Suggest adding braces around empty body', + 'patterns':[r".*: warning: suggest braces around empty body in an 'if' statement", + r".*: warning: empty body in an if-statement", + r".*: warning: suggest braces around empty body in an 'else' statement", + r".*: warning: empty body in an else-statement"] }, + { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wparentheses', + 'description':'Suggest adding parentheses', + 'patterns':[r".*: warning: suggest explicit braces to avoid ambiguous 'else'", + r".*: warning: suggest parentheses around arithmetic in operand of '.+'", + r".*: warning: suggest parentheses around comparison in operand of '.+'", + r".*: warning: suggest parentheses around '.+?' .+ '.+?'", + r".*: warning: suggest parentheses around assignment used as truth value"] }, + { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'', + 'description':'Static variable used in non-static inline function', + 'patterns':[r".*: warning: '.+' is static but used in inline function '.+' which is not static"] }, + { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wimplicit int', + 'description':'No type or storage class (will default to int)', + 'patterns':[r".*: warning: data definition has no type or storage class"] }, + { 'category':'cont.', 'severity':severity.SKIP, 'members':[], 'option':'', + 'description':'', + 'patterns':[r".*: warning: type defaults to 'int' in declaration of '.+'"] }, + { 'category':'cont.', 'severity':severity.SKIP, 'members':[], 'option':'', + 'description':'', + 'patterns':[r".*: warning: parameter names \(without types\) in function declaration"] }, + { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wstrict-aliasing', + 'description':'Dereferencing <foo> breaks strict aliasing rules', + 'patterns':[r".*: warning: dereferencing .* break strict-aliasing rules"] }, + { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wpointer-to-int-cast', + 'description':'Cast from pointer to integer of different size', + 'patterns':[r".*: warning: cast from pointer to integer of different size"] }, + { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wint-to-pointer-cast', + 'description':'Cast to pointer from integer of different size', + 'patterns':[r".*: warning: cast to pointer from integer of different size"] }, + { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'', + 'description':'Symbol redefined', + 'patterns':[r".*: warning: "".+"" redefined"] }, + { 'category':'cont.', 'severity':severity.SKIP, 'members':[], 'option':'', + 'description':'', + 'patterns':[r".*: warning: this is the location of the previous definition"] }, + { 'category':'ld', 'severity':severity.MEDIUM, 'members':[], 'option':'', + 'description':'ld: type and size of dynamic symbol are not defined', + 'patterns':[r".*: warning: type and size of dynamic symbol `.+' are not defined"] }, + { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'', + 'description':'Pointer from integer without cast', + 'patterns':[r".*: warning: assignment makes pointer from integer without a cast"] }, + { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'', + 'description':'Pointer from integer without cast', + 'patterns':[r".*: warning: passing argument [0-9]+ of '.+' makes pointer from integer without a cast"] }, + { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'', + 'description':'Integer from pointer without cast', + 'patterns':[r".*: warning: assignment makes integer from pointer without a cast"] }, + { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'', + 'description':'Integer from pointer without cast', + 'patterns':[r".*: warning: passing argument [0-9]+ of '.+' makes integer from pointer without a cast"] }, + { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'', + 'description':'Integer from pointer without cast', + 'patterns':[r".*: warning: return makes integer from pointer without a cast"] }, + { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wunknown-pragmas', + 'description':'Ignoring pragma', + 'patterns':[r".*: warning: ignoring #pragma .+"] }, + { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wclobbered', + 'description':'Variable might be clobbered by longjmp or vfork', + 'patterns':[r".*: warning: variable '.+' might be clobbered by 'longjmp' or 'vfork'"] }, + { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wclobbered', + 'description':'Argument might be clobbered by longjmp or vfork', + 'patterns':[r".*: warning: argument '.+' might be clobbered by 'longjmp' or 'vfork'"] }, + { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wredundant-decls', + 'description':'Redundant declaration', + 'patterns':[r".*: warning: redundant redeclaration of '.+'"] }, + { 'category':'cont.', 'severity':severity.SKIP, 'members':[], 'option':'', + 'description':'', + 'patterns':[r".*: warning: previous declaration of '.+' was here"] }, + { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wswitch-enum', + 'description':'Enum value not handled in switch', + 'patterns':[r".*: warning: enumeration value '.+' not handled in switch"] }, + { 'category':'java', 'severity':severity.MEDIUM, 'members':[], 'option':'-encoding', + 'description':'Java: Non-ascii characters used, but ascii encoding specified', + 'patterns':[r".*: warning: unmappable character for encoding ascii"] }, + { 'category':'java', 'severity':severity.MEDIUM, 'members':[], 'option':'', + 'description':'Java: Non-varargs call of varargs method with inexact argument type for last parameter', + 'patterns':[r".*: warning: non-varargs call of varargs method with inexact argument type for last parameter"] }, + { 'category':'aapt', 'severity':severity.MEDIUM, 'members':[], 'option':'', + 'description':'aapt: String marked untranslatable, but translation exists', + 'patterns':[r".*: warning: string '.+' in .* marked untranslatable but exists in locale '??_??'"] }, + { 'category':'aapt', 'severity':severity.MEDIUM, 'members':[], 'option':'', + 'description':'aapt: empty span in string', + 'patterns':[r".*: warning: empty '.+' span found in text '.+"] }, + { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'', + 'description':'Taking address of temporary', + 'patterns':[r".*: warning: taking address of temporary"] }, + { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'', + 'description':'Possible broken line continuation', + 'patterns':[r".*: warning: backslash and newline separated by space"] }, + { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Warray-bounds', + 'description':'Array subscript out of bounds', + 'patterns':[r".*: warning: array subscript is above array bounds"] }, + { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'', + 'description':'Decimal constant is unsigned only in ISO C90', + 'patterns':[r".*: warning: this decimal constant is unsigned only in ISO C90"] }, + { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wmain', + 'description':'main is usually a function', + 'patterns':[r".*: warning: 'main' is usually a function"] }, + { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'', + 'description':'Typedef ignored', + 'patterns':[r".*: warning: 'typedef' was ignored in this declaration"] }, + { 'category':'C/C++', 'severity':severity.HIGH, 'members':[], 'option':'-Waddress', + 'description':'Address always evaluates to true', + 'patterns':[r".*: warning: the address of '.+' will always evaluate as 'true'"] }, + { 'category':'C/C++', 'severity':severity.FIXMENOW, 'members':[], 'option':'', + 'description':'Freeing a non-heap object', + 'patterns':[r".*: warning: attempt to free a non-heap object '.+'"] }, + { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wchar-subscripts', + 'description':'Array subscript has type char', + 'patterns':[r".*: warning: array subscript has type 'char'"] }, + { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'', + 'description':'Constant too large for type', + 'patterns':[r".*: warning: integer constant is too large for '.+' type"] }, + { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Woverflow', + 'description':'Constant too large for type, truncated', + 'patterns':[r".*: warning: large integer implicitly truncated to unsigned type"] }, + { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Woverflow', + 'description':'Overflow in implicit constant conversion', + 'patterns':[r".*: warning: overflow in implicit constant conversion"] }, + { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'', + 'description':'Declaration does not declare anything', + 'patterns':[r".*: warning: declaration 'class .+' does not declare anything"] }, + { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wreorder', + 'description':'Initialization order will be different', + 'patterns':[r".*: warning: '.+' will be initialized after"] }, + { 'category':'cont.', 'severity':severity.SKIP, 'members':[], 'option':'', + 'description':'', + 'patterns':[r".*: warning: '.+'"] }, + { 'category':'cont.', 'severity':severity.SKIP, 'members':[], 'option':'', + 'description':'', + 'patterns':[r".*: warning: when initialized here"] }, + { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wmissing-parameter-type', + 'description':'Parameter type not specified', + 'patterns':[r".*: warning: type of '.+' defaults to 'int'"] }, + { 'category':'gcc', 'severity':severity.MEDIUM, 'members':[], 'option':'', + 'description':'Invalid option for C file', + 'patterns':[r".*: warning: command line option "".+"" is valid for C\+\+\/ObjC\+\+ but not for C"] }, + { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'', + 'description':'User warning', + 'patterns':[r".*: warning: #warning "".+"""] }, + { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wextra', + 'description':'Dereferencing void*', + 'patterns':[r".*: warning: dereferencing 'void \*' pointer"] }, + { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wextra', + 'description':'Comparison of pointer to zero', + 'patterns':[r".*: warning: ordered comparison of pointer with integer zero"] }, + { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wwrite-strings', + 'description':'Conversion of string constant to non-const char*', + 'patterns':[r".*: warning: deprecated conversion from string constant to '.+'"] }, + { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wstrict-prototypes', + 'description':'Function declaration isn''t a prototype', + 'patterns':[r".*: warning: function declaration isn't a prototype"] }, + { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wignored-qualifiers', + 'description':'Type qualifiers ignored on function return value', + 'patterns':[r".*: warning: type qualifiers ignored on function return type"] }, + { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'', + 'description':'<foo> declared inside parameter list, scope limited to this definition', + 'patterns':[r".*: warning: '.+' declared inside parameter list"] }, + { 'category':'cont.', 'severity':severity.SKIP, 'members':[], 'option':'', + 'description':'', + 'patterns':[r".*: warning: its scope is only this definition or declaration, which is probably not what you want"] }, + { 'category':'C/C++', 'severity':severity.LOW, 'members':[], 'option':'-Wcomment', + 'description':'Line continuation inside comment', + 'patterns':[r".*: warning: multi-line comment"] }, + { 'category':'C/C++', 'severity':severity.HARMLESS, 'members':[], 'option':'', + 'description':'Extra tokens after #endif', + 'patterns':[r".*: warning: extra tokens at end of #endif directive"] }, + { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wenum-compare', + 'description':'Comparison between different enums', + 'patterns':[r".*: warning: comparison between 'enum .+' and 'enum .+'"] }, + { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wconversion', + 'description':'Implicit conversion of negative number to unsigned type', + 'patterns':[r".*: warning: converting negative value '.+' to '.+'"] }, + { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'', + 'description':'Passing NULL as non-pointer argument', + 'patterns':[r".*: warning: passing NULL to non-pointer argument 3 of '.+'"] }, + { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wctor-dtor-privacy', + 'description':'Class seems unusable because of private ctor/dtor' , + 'patterns':[r".*: warning: all member functions in class '.+' are private"] }, + # skip this next one, because it only points out some RefBase-based classes where having a private destructor is perfectly fine + { 'category':'C/C++', 'severity':severity.SKIP, 'members':[], 'option':'-Wctor-dtor-privacy', + 'description':'Class seems unusable because of private ctor/dtor' , + 'patterns':[r".*: warning: 'class .+' only defines a private destructor and has no friends"] }, + { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wctor-dtor-privacy', + 'description':'Class seems unusable because of private ctor/dtor' , + 'patterns':[r".*: warning: 'class .+' only defines private constructors and has no friends"] }, + { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wpointer-arith', + 'description':'void* used in arithmetic' , + 'patterns':[r".*: warning: pointer of type 'void \*' used in (arithmetic|subtraction)", + r".*: warning: wrong type argument to increment"] }, + { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wsign-promo', + 'description':'Overload resolution chose to promote from unsigned or enum to signed type' , + 'patterns':[r".*: warning: passing '.+' chooses 'int' over '.* int'"] }, + { 'category':'cont.', 'severity':severity.SKIP, 'members':[], 'option':'', + 'description':'', + 'patterns':[r".*: warning: in call to '.+'"] }, + + # these next ones are to deal with formatting problems resulting from the log being mixed up by 'make -j' + { 'category':'C/C++', 'severity':severity.SKIP, 'members':[], 'option':'', + 'description':'', + 'patterns':[r".*: warning: ,$"] }, + { 'category':'C/C++', 'severity':severity.SKIP, 'members':[], 'option':'', + 'description':'', + 'patterns':[r".*: warning: $"] }, + { 'category':'C/C++', 'severity':severity.SKIP, 'members':[], 'option':'', + 'description':'', + 'patterns':[r".*: warning: In file included from .+,"] }, + + # catch-all for warnings this script doesn't know about yet + { 'category':'C/C++', 'severity':severity.UNKNOWN, 'members':[], 'option':'', + 'description':'Unclassified/unrecognized warnings', + 'patterns':[r".*: warning: .+"] }, +] + +anchor = 0 +cur_row_color = 0 +row_colors = [ 'e0e0e0', 'd0d0d0' ] + +def output(text): + print text, + +def htmlbig(param): + return '<font size="+2">' + param + '</font>' + +def dumphtmlprologue(title): + output('<html>\n<head>\n<title>' + title + '</title>\n<body>\n') + output(htmlbig(title)) + output('<p>\n') + +def tablerow(text): + global cur_row_color + output('<tr bgcolor="' + row_colors[cur_row_color] + '"><td colspan="2">',) + cur_row_color = 1 - cur_row_color + output(text,) + output('</td></tr>') + +def begintable(text, backgroundcolor): + global anchor + output('<table border="1" rules="cols" frame="box" width="100%" bgcolor="black"><tr bgcolor="' + + backgroundcolor + '"><a name="anchor' + str(anchor) + '"><td>') + output(htmlbig(text[0]) + '<br>') + for i in text[1:]: + output(i + '<br>') + output('</td>') + output('<td width="100" bgcolor="grey"><a align="right" href="#anchor' + str(anchor-1) + + '">previous</a><br><a align="right" href="#anchor' + str(anchor+1) + '">next</a>') + output('</td></a></tr>') + anchor += 1 + +def endtable(): + output('</table><p>') + + +# dump some stats about total number of warnings and such +def dumpstats(): + known = 0 + unknown = 0 + for i in warnpatterns: + if i['severity'] == severity.UNKNOWN: + unknown += len(i['members']) + elif i['severity'] != severity.SKIP: + known += len(i['members']) + output('Number of classified warnings: <b>' + str(known) + '</b><br>' ) + output('Number of unclassified warnings: <b>' + str(unknown) + '</b><br>') + total = unknown + known + output('Total number of warnings: <b>' + str(total) + '</b>') + if total < 1000: + output('(low count may indicate incremental build)') + output('<p>') + +def allpatterns(cat): + pats = '' + for i in cat['patterns']: + pats += i + pats += ' / ' + return pats + +def descriptionfor(cat): + if cat['description'] != '': + return cat['description'] + return allpatterns(cat) + + +# show which warnings no longer occur +def dumpfixed(): + tablestarted = False + for i in warnpatterns: + if len(i['members']) == 0 and i['severity'] != severity.SKIP: + if tablestarted == False: + tablestarted = True + begintable(['Fixed warnings', 'No more occurences. Please consider turning these in to errors if possible, before they are reintroduced in to the build'], 'blue') + tablerow(i['description'] + ' (' + allpatterns(i) + ') ' + i['option']) + if tablestarted: + endtable() + + +# dump a category, provided it is not marked as 'SKIP' and has more than 0 occurrences +def dumpcategory(cat): + if cat['severity'] != severity.SKIP and len(cat['members']) != 0: + header = [descriptionfor(cat),str(len(cat['members'])) + ' occurences:'] + if cat['option'] != '': + header[1:1] = [' (related option: ' + cat['option'] +')'] + begintable(header, colorforseverity(cat['severity'])) + for i in cat['members']: + tablerow(i) + endtable() + + +# dump everything for a given severity +def dumpseverity(sev): + for i in warnpatterns: + if i['severity'] == sev: + dumpcategory(i) + + +def classifywarning(line): + for i in warnpatterns: + for pat in i['patterns']: + if re.match(pat, line): + i['members'].append(line) + return + else: + # If we end up here, there was a problem parsing the log + # probably caused by 'make -j' mixing the output from + # 2 or more concurrent compiles + pass + + + +infile = open(sys.argv[1], 'r') +warnings = [] + +platformversion = 'unknown' +targetproduct = 'unknown' +targetvariant = 'unknown' +linecounter = 0 + +warningpattern = re.compile('.* warning:.*') + +# read the log file and classify all the warnings +lastmatchedline = '' +for line in infile: + if warningpattern.match(line): + if line != lastmatchedline: + classifywarning(line) + lastmatchedline = line + else: + # save a little bit of time by only doing this for the first few lines + if linecounter < 50: + linecounter +=1 + m = re.search('(?<=^PLATFORM_VERSION=).*', line) + if m != None: + platformversion = m.group(0) + m = re.search('(?<=^TARGET_PRODUCT=).*', line) + if m != None: + targetproduct = m.group(0) + m = re.search('(?<=^TARGET_BUILD_VARIANT=).*', line) + if m != None: + targetvariant = m.group(0) + + +# dump the html output to stdout +dumphtmlprologue('Warnings for ' + platformversion + ' - ' + targetproduct + ' - ' + targetvariant) +dumpstats() +dumpseverity(severity.FIXMENOW) +dumpseverity(severity.HIGH) +dumpseverity(severity.MEDIUM) +dumpseverity(severity.LOW) +dumpseverity(severity.HARMLESS) +dumpseverity(severity.UNKNOWN) +dumpfixed() + + + + + |