forked from openkylin/platform_build
Merge \\\\"Add option to dump HTML warnings per project.\\\\" am: 620ce44a7a
am: 1955ea00a0
am: 8dcdbff9e7
am: 7d23423a0f
Change-Id: Ieccdd1b47a6cd72b3ea0775400f048e91ccb4351
This commit is contained in:
commit
67cf34d300
138
tools/warn.py
138
tools/warn.py
|
@ -10,6 +10,10 @@ parser.add_argument('--gencsv',
|
||||||
help='Generate a CSV file with number of various warnings',
|
help='Generate a CSV file with number of various warnings',
|
||||||
action="store_true",
|
action="store_true",
|
||||||
default=False)
|
default=False)
|
||||||
|
parser.add_argument('--byproject',
|
||||||
|
help='Separate warnings in HTML output by project names',
|
||||||
|
action="store_true",
|
||||||
|
default=False)
|
||||||
parser.add_argument('--url',
|
parser.add_argument('--url',
|
||||||
help='Root URL of an Android source code tree prefixed '
|
help='Root URL of an Android source code tree prefixed '
|
||||||
'before files in warnings')
|
'before files in warnings')
|
||||||
|
@ -1660,6 +1664,7 @@ warnpatterns = [
|
||||||
{ 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'',
|
{ 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'',
|
||||||
'description':'Undefined result',
|
'description':'Undefined result',
|
||||||
'patterns':[r".*: warning: The result of .+ is undefined",
|
'patterns':[r".*: warning: The result of .+ is undefined",
|
||||||
|
r".*: warning: passing an object that .+ has undefined behavior \[-Wvarargs\]",
|
||||||
r".*: warning: 'this' pointer cannot be null in well-defined C\+\+ code;",
|
r".*: warning: 'this' pointer cannot be null in well-defined C\+\+ code;",
|
||||||
r".*: warning: shifting a negative signed value is undefined"] },
|
r".*: warning: shifting a negative signed value is undefined"] },
|
||||||
{ 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'',
|
{ 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'',
|
||||||
|
@ -1811,43 +1816,52 @@ warnpatterns = [
|
||||||
# A list of [project_name, file_path_pattern].
|
# A list of [project_name, file_path_pattern].
|
||||||
# project_name should not contain comma, to be used in CSV output.
|
# project_name should not contain comma, to be used in CSV output.
|
||||||
projectlist = [
|
projectlist = [
|
||||||
['art', r"(^|.*/)art/.*: warning:"],
|
['art', r"(^|.*/)art/.*: warning:"],
|
||||||
['bionic', r"(^|.*/)bionic/.*: warning:"],
|
['bionic', r"(^|.*/)bionic/.*: warning:"],
|
||||||
['bootable', r"(^|.*/)bootable/.*: warning:"],
|
['bootable', r"(^|.*/)bootable/.*: warning:"],
|
||||||
['build', r"(^|.*/)build/.*: warning:"],
|
['build', r"(^|.*/)build/.*: warning:"],
|
||||||
['cts', r"(^|.*/)cts/.*: warning:"],
|
['cts', r"(^|.*/)cts/.*: warning:"],
|
||||||
['dalvik', r"(^|.*/)dalvik/.*: warning:"],
|
['dalvik', r"(^|.*/)dalvik/.*: warning:"],
|
||||||
['developers', r"(^|.*/)developers/.*: warning:"],
|
['developers', r"(^|.*/)developers/.*: warning:"],
|
||||||
['development', r"(^|.*/)development/.*: warning:"],
|
['development', r"(^|.*/)development/.*: warning:"],
|
||||||
['device', r"(^|.*/)device/.*: warning:"],
|
['device', r"(^|.*/)device/.*: warning:"],
|
||||||
['doc', r"(^|.*/)doc/.*: warning:"],
|
['doc', r"(^|.*/)doc/.*: warning:"],
|
||||||
['external', r"(^|.*/)external/.*: warning:"],
|
# match external/google* before external/
|
||||||
['frameworks', r"(^|.*/)frameworks/.*: warning:"],
|
['external/google', r"(^|.*/)external/google.*: warning:"],
|
||||||
['hardware', r"(^|.*/)hardware/.*: warning:"],
|
['external/non-google', r"(^|.*/)external/.*: warning:"],
|
||||||
['kernel', r"(^|.*/)kernel/.*: warning:"],
|
['frameworks', r"(^|.*/)frameworks/.*: warning:"],
|
||||||
['libcore', r"(^|.*/)libcore/.*: warning:"],
|
['hardware', r"(^|.*/)hardware/.*: warning:"],
|
||||||
['libnativehelper', r"(^|.*/)libnativehelper/.*: warning:"],
|
['kernel', r"(^|.*/)kernel/.*: warning:"],
|
||||||
['ndk', r"(^|.*/)ndk/.*: warning:"],
|
['libcore', r"(^|.*/)libcore/.*: warning:"],
|
||||||
['packages', r"(^|.*/)packages/.*: warning:"],
|
['libnativehelper', r"(^|.*/)libnativehelper/.*: warning:"],
|
||||||
['pdk', r"(^|.*/)pdk/.*: warning:"],
|
['ndk', r"(^|.*/)ndk/.*: warning:"],
|
||||||
['prebuilts', r"(^|.*/)prebuilts/.*: warning:"],
|
['packages', r"(^|.*/)packages/.*: warning:"],
|
||||||
['system', r"(^|.*/)system/.*: warning:"],
|
['pdk', r"(^|.*/)pdk/.*: warning:"],
|
||||||
['toolchain', r"(^|.*/)toolchain/.*: warning:"],
|
['prebuilts', r"(^|.*/)prebuilts/.*: warning:"],
|
||||||
['test', r"(^|.*/)test/.*: warning:"],
|
['system', r"(^|.*/)system/.*: warning:"],
|
||||||
['tools', r"(^|.*/)tools/.*: warning:"],
|
['toolchain', r"(^|.*/)toolchain/.*: warning:"],
|
||||||
['vendor', r"(^|.*/)vendor/.*: warning:"],
|
['test', r"(^|.*/)test/.*: warning:"],
|
||||||
['out/obj', r".*/(gen|obj[^/]*)/(include|EXECUTABLES|SHARED_LIBRARIES|STATIC_LIBRARIES)/.*: warning:"],
|
['tools', r"(^|.*/)tools/.*: warning:"],
|
||||||
['other', r".*: warning:"],
|
# match vendor/google* before vendor/
|
||||||
|
['vendor/google', r"(^|.*/)vendor/google.*: warning:"],
|
||||||
|
['vendor/non-google', r"(^|.*/)vendor/.*: warning:"],
|
||||||
|
# keep out/obj and other patterns at the end.
|
||||||
|
['out/obj', r".*/(gen|obj[^/]*)/(include|EXECUTABLES|SHARED_LIBRARIES|STATIC_LIBRARIES)/.*: warning:"],
|
||||||
|
['other', r".*: warning:"],
|
||||||
]
|
]
|
||||||
|
|
||||||
projectpatterns = []
|
projectpatterns = []
|
||||||
for p in projectlist:
|
for p in projectlist:
|
||||||
projectpatterns.append({'description':p[0], 'members':[], 'pattern':re.compile(p[1])})
|
projectpatterns.append({'description':p[0], 'members':[], 'pattern':re.compile(p[1])})
|
||||||
|
|
||||||
# Each warning pattern has a dictionary that maps
|
# Each warning pattern has 3 dictionaries:
|
||||||
# a project name to number of warnings in that project.
|
# (1) 'projects' maps a project name to number of warnings in that project.
|
||||||
|
# (2) 'projectanchor' maps a project name to its anchor number for HTML.
|
||||||
|
# (3) 'projectwarning' maps a project name to a list of warning of that project.
|
||||||
for w in warnpatterns:
|
for w in warnpatterns:
|
||||||
w['projects'] = {}
|
w['projects'] = {}
|
||||||
|
w['projectanchor'] = {}
|
||||||
|
w['projectwarning'] = {}
|
||||||
|
|
||||||
platformversion = 'unknown'
|
platformversion = 'unknown'
|
||||||
targetproduct = 'unknown'
|
targetproduct = 'unknown'
|
||||||
|
@ -1952,17 +1966,12 @@ def dumpseverity(sev):
|
||||||
output('<blockquote>\n')
|
output('<blockquote>\n')
|
||||||
for i in warnpatterns:
|
for i in warnpatterns:
|
||||||
if i['severity'] == sev and len(i['members']) > 0:
|
if i['severity'] == sev and len(i['members']) > 0:
|
||||||
output('\n<table frame="box">\n')
|
|
||||||
anchor += 1
|
anchor += 1
|
||||||
i['anchor'] = str(anchor)
|
i['anchor'] = str(anchor)
|
||||||
mark = str(anchor) + '_mark'
|
if args.byproject:
|
||||||
output('<tr bgcolor="' + colorforseverity(sev) + '">' +
|
dumpcategorybyproject(sev, i)
|
||||||
'<td><button class="bt" id="' + mark +
|
else:
|
||||||
'" onclick="expand(\'' + str(anchor) + '\');">' +
|
dumpcategory(sev, i)
|
||||||
'⊕</button> ' + descriptionfor(i) +
|
|
||||||
' (' + str(len(i['members'])) + ')</td></tr>\n')
|
|
||||||
output('</table>\n')
|
|
||||||
dumpcategory(i)
|
|
||||||
output('</blockquote>\n')
|
output('</blockquote>\n')
|
||||||
|
|
||||||
def allpatterns(cat):
|
def allpatterns(cat):
|
||||||
|
@ -2017,19 +2026,35 @@ def warningwithurl(line):
|
||||||
else:
|
else:
|
||||||
return '<a href="' + args.url + '/' + filepath + '">' + filepath + '</a>:' + linenumber + ':' + warning
|
return '<a href="' + args.url + '/' + filepath + '">' + filepath + '</a>:' + linenumber + ':' + warning
|
||||||
|
|
||||||
# dump a category, provided it is not marked as 'SKIP' and has more than 0 occurrences
|
def dumpgroup(sev, anchor, description, warnings):
|
||||||
def dumpcategory(cat):
|
mark = anchor + '_mark'
|
||||||
if cat['severity'] != severity.SKIP and len(cat['members']) != 0:
|
output('\n<table frame="box">\n')
|
||||||
header = [descriptionfor(cat),str(len(cat['members'])) + ' occurences:']
|
output('<tr bgcolor="' + colorforseverity(sev) + '">' +
|
||||||
if cat['option'] != '':
|
'<td><button class="bt" id="' + mark +
|
||||||
header[1:1] = [' (related option: ' + cat['option'] +')']
|
'" onclick="expand(\'' + anchor + '\');">' +
|
||||||
|
'⊕</button> ' + description + '</td></tr>\n')
|
||||||
|
output('</table>\n')
|
||||||
|
output('<div id="' + anchor + '" style="display:none;">')
|
||||||
|
output('<table>\n')
|
||||||
|
for i in warnings:
|
||||||
|
tablerow(warningwithurl(i))
|
||||||
|
output('</table></div>\n')
|
||||||
|
|
||||||
output('<div id="' + cat['anchor'] + '" style="display:none;">')
|
# dump warnings in a category
|
||||||
output('<table>\n')
|
def dumpcategory(sev, cat):
|
||||||
for i in cat['members']:
|
description = descriptionfor(cat) + ' (' + str(len(cat['members'])) + ')'
|
||||||
tablerow(warningwithurl(i))
|
dumpgroup(sev, cat['anchor'], description, cat['members'])
|
||||||
output('</table></div>\n')
|
|
||||||
|
|
||||||
|
# similar to dumpcategory but output one table per project.
|
||||||
|
def dumpcategorybyproject(sev, cat):
|
||||||
|
warning = descriptionfor(cat)
|
||||||
|
projects = cat['projectwarning'].keys()
|
||||||
|
projects.sort()
|
||||||
|
for p in projects:
|
||||||
|
anchor = cat['projectanchor'][p]
|
||||||
|
projectwarnings = cat['projectwarning'][p]
|
||||||
|
description = '{}, in {} ({})'.format(warning, p, len(projectwarnings))
|
||||||
|
dumpgroup(sev, anchor, description, projectwarnings)
|
||||||
|
|
||||||
def findproject(line):
|
def findproject(line):
|
||||||
for p in projectpatterns:
|
for p in projectpatterns:
|
||||||
|
@ -2038,15 +2063,26 @@ def findproject(line):
|
||||||
return '???'
|
return '???'
|
||||||
|
|
||||||
def classifywarning(line):
|
def classifywarning(line):
|
||||||
|
global anchor
|
||||||
for i in warnpatterns:
|
for i in warnpatterns:
|
||||||
for cpat in i['compiledpatterns']:
|
for cpat in i['compiledpatterns']:
|
||||||
if cpat.match(line):
|
if cpat.match(line):
|
||||||
i['members'].append(line)
|
i['members'].append(line)
|
||||||
pname = findproject(line)
|
pname = findproject(line)
|
||||||
|
# Count warnings by project.
|
||||||
if pname in i['projects']:
|
if pname in i['projects']:
|
||||||
i['projects'][pname] += 1
|
i['projects'][pname] += 1
|
||||||
else:
|
else:
|
||||||
i['projects'][pname] = 1
|
i['projects'][pname] = 1
|
||||||
|
# Collect warnings by project.
|
||||||
|
if args.byproject:
|
||||||
|
if pname in i['projectwarning']:
|
||||||
|
i['projectwarning'][pname].append(line)
|
||||||
|
else:
|
||||||
|
i['projectwarning'][pname] = [line]
|
||||||
|
if pname not in i['projectanchor']:
|
||||||
|
anchor += 1
|
||||||
|
i['projectanchor'][pname] = str(anchor)
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
# If we end up here, there was a problem parsing the log
|
# If we end up here, there was a problem parsing the log
|
||||||
|
|
Loading…
Reference in New Issue