This provides a report of the top incomplete variables reported by the ValueFlow analysis. This is based on the implementation of the existing `--check-library` reports.
This commit is contained in:
parent
3cbbb77335
commit
51d1758720
|
@ -26,7 +26,7 @@ from urllib.parse import urlparse
|
||||||
# Version scheme (MAJOR.MINOR.PATCH) should orientate on "Semantic Versioning" https://semver.org/
|
# Version scheme (MAJOR.MINOR.PATCH) should orientate on "Semantic Versioning" https://semver.org/
|
||||||
# Every change in this script should result in increasing the version number accordingly (exceptions may be cosmetic
|
# Every change in this script should result in increasing the version number accordingly (exceptions may be cosmetic
|
||||||
# changes)
|
# changes)
|
||||||
SERVER_VERSION = "1.3.41"
|
SERVER_VERSION = "1.3.42"
|
||||||
|
|
||||||
OLD_VERSION = '2.11'
|
OLD_VERSION = '2.11'
|
||||||
|
|
||||||
|
@ -111,7 +111,7 @@ def overviewReport() -> str:
|
||||||
#html += '<a href="head-valueFlowBailout">valueFlowBailout</a><br>\n'
|
#html += '<a href="head-valueFlowBailout">valueFlowBailout</a><br>\n'
|
||||||
#html += '<a href="head-bailoutUninitVar">bailoutUninitVar</a><br>\n'
|
#html += '<a href="head-bailoutUninitVar">bailoutUninitVar</a><br>\n'
|
||||||
#html += '<a href="head-symbolDatabaseWarning">symbolDatabaseWarning</a><br>\n'
|
#html += '<a href="head-symbolDatabaseWarning">symbolDatabaseWarning</a><br>\n'
|
||||||
#html += '<a href="head-valueFlowBailoutIncompleteVar">valueFlowBailoutIncompleteVar</a><br>\n'
|
html += '<a href="value_flow_bailout_incomplete_var.html">valueFlowBailoutIncompleteVar report</a><br>\n'
|
||||||
html += '<br>\n'
|
html += '<br>\n'
|
||||||
html += 'Important errors:<br>\n'
|
html += 'Important errors:<br>\n'
|
||||||
html += '<a href="head-cppcheckError">cppcheckError</a><br>\n'
|
html += '<a href="head-cppcheckError">cppcheckError</a><br>\n'
|
||||||
|
@ -897,17 +897,23 @@ def timeReportSlow(resultPath: str) -> str:
|
||||||
|
|
||||||
|
|
||||||
def check_library_report(result_path: str, message_id: str) -> str:
|
def check_library_report(result_path: str, message_id: str) -> str:
|
||||||
if message_id not in ('checkLibraryNoReturn', 'checkLibraryFunction', 'checkLibraryUseIgnore', 'checkLibraryCheckType'):
|
if message_id not in ('checkLibraryNoReturn', 'checkLibraryFunction', 'checkLibraryUseIgnore', 'checkLibraryCheckType', 'valueFlowBailoutIncompleteVar'):
|
||||||
error_message = 'Invalid value ' + message_id + ' for message_id parameter.'
|
error_message = 'Invalid value ' + message_id + ' for message_id parameter.'
|
||||||
print_ts(error_message)
|
print_ts(error_message)
|
||||||
return error_message
|
return error_message
|
||||||
|
|
||||||
if message_id == 'checkLibraryCheckType':
|
if message_id == 'valueFlowBailoutIncompleteVar':
|
||||||
|
metric = 'variables'
|
||||||
|
m_column = 'Variable'
|
||||||
|
metric_link = 'incomplete_var'
|
||||||
|
elif message_id == 'checkLibraryCheckType':
|
||||||
metric = 'types'
|
metric = 'types'
|
||||||
m_column = 'Type'
|
m_column = 'Type'
|
||||||
|
metric_link = 'check_library'
|
||||||
else:
|
else:
|
||||||
metric = 'functions'
|
metric = 'functions'
|
||||||
m_column = 'Function'
|
m_column = 'Function'
|
||||||
|
metric_link = 'check_library'
|
||||||
|
|
||||||
functions_shown_max = 5000
|
functions_shown_max = 5000
|
||||||
html = '<!DOCTYPE html>\n'
|
html = '<!DOCTYPE html>\n'
|
||||||
|
@ -933,17 +939,24 @@ def check_library_report(result_path: str, message_id: str) -> str:
|
||||||
else:
|
else:
|
||||||
# Current package, parse on
|
# Current package, parse on
|
||||||
continue
|
continue
|
||||||
if line == 'info messages:\n':
|
if message_id != 'valueFlowBailoutIncompleteVar':
|
||||||
info_messages = True
|
if line == 'info messages:\n':
|
||||||
if not info_messages:
|
info_messages = True
|
||||||
continue
|
if not info_messages:
|
||||||
|
continue
|
||||||
if line.endswith('[' + message_id + ']\n'):
|
if line.endswith('[' + message_id + ']\n'):
|
||||||
if message_id == 'checkLibraryFunction':
|
if message_id == 'valueFlowBailoutIncompleteVar':
|
||||||
function_name = line[(line.find('for function ') + len('for function ')):line.rfind('[') - 1]
|
marker = 'incomplete variable '
|
||||||
|
function_name = line[(line.find(marker) + len(marker)):line.rfind('[') - 1]
|
||||||
|
elif message_id == 'checkLibraryFunction':
|
||||||
|
marker = 'for function '
|
||||||
|
function_name = line[(line.find(marker) + len(marker)):line.rfind('[') - 1]
|
||||||
elif message_id == 'checkLibraryCheckType':
|
elif message_id == 'checkLibraryCheckType':
|
||||||
function_name = line[(line.find('configuration for ') + len('configuration for ')):line.rfind('[') - 1]
|
marker = 'configuration for '
|
||||||
|
function_name = line[(line.find(marker) + len(marker)):line.rfind('[') - 1]
|
||||||
else:
|
else:
|
||||||
function_name = line[(line.find(': Function ') + len(': Function ')):line.rfind('should have') - 1]
|
marker = ': Function '
|
||||||
|
function_name = line[(line.find(marker) + len(marker)):line.rfind('should have') - 1]
|
||||||
function_counts[function_name] = function_counts.setdefault(function_name, 0) + 1
|
function_counts[function_name] = function_counts.setdefault(function_name, 0) + 1
|
||||||
|
|
||||||
function_details_list = []
|
function_details_list = []
|
||||||
|
@ -951,7 +964,7 @@ def check_library_report(result_path: str, message_id: str) -> str:
|
||||||
if len(function_details_list) >= functions_shown_max:
|
if len(function_details_list) >= functions_shown_max:
|
||||||
break
|
break
|
||||||
function_details_list.append(str(count).rjust(column_widths[0]) + ' ' +
|
function_details_list.append(str(count).rjust(column_widths[0]) + ' ' +
|
||||||
'<a href="check_library-' + urllib.parse.quote_plus(function_name) + '">' + function_name + '</a>\n')
|
'<a href="' + metric_link + '-' + urllib.parse.quote_plus(function_name) + '">' + function_name + '</a>\n')
|
||||||
|
|
||||||
html += ''.join(function_details_list)
|
html += ''.join(function_details_list)
|
||||||
html += '</pre>\n'
|
html += '</pre>\n'
|
||||||
|
@ -961,12 +974,15 @@ def check_library_report(result_path: str, message_id: str) -> str:
|
||||||
|
|
||||||
|
|
||||||
# Lists all checkLibrary* messages regarding the given function name
|
# Lists all checkLibrary* messages regarding the given function name
|
||||||
def check_library_function_name(result_path: str, function_name: str) -> str:
|
def check_library_function_name(result_path: str, function_name: str, is_var: bool=False) -> str:
|
||||||
function_name = urllib.parse.unquote_plus(function_name)
|
if is_var:
|
||||||
if function_name.endswith('()'):
|
id = '[valueFlowBailoutIncompleteVar'
|
||||||
id = '[checkLibrary'
|
|
||||||
else:
|
else:
|
||||||
id = '[checkLibraryCheckType]'
|
function_name = urllib.parse.unquote_plus(function_name)
|
||||||
|
if function_name.endswith('()'):
|
||||||
|
id = '[checkLibrary'
|
||||||
|
else:
|
||||||
|
id = '[checkLibraryCheckType]'
|
||||||
output_lines_list = []
|
output_lines_list = []
|
||||||
for filename in glob.glob(result_path + '/*'):
|
for filename in glob.glob(result_path + '/*'):
|
||||||
if not os.path.isfile(filename) or filename.endswith('.diff'):
|
if not os.path.isfile(filename) or filename.endswith('.diff'):
|
||||||
|
@ -977,12 +993,16 @@ def check_library_function_name(result_path: str, function_name: str) -> str:
|
||||||
for line in open(filename, 'rt'):
|
for line in open(filename, 'rt'):
|
||||||
if line.startswith('ftp://'):
|
if line.startswith('ftp://'):
|
||||||
url = line
|
url = line
|
||||||
elif line.startswith('cppcheck-options:'):
|
|
||||||
cppcheck_options = line
|
|
||||||
elif line == 'info messages:\n':
|
|
||||||
info_messages = True
|
|
||||||
if not info_messages:
|
|
||||||
continue
|
continue
|
||||||
|
if line.startswith('cppcheck-options:'):
|
||||||
|
cppcheck_options = line
|
||||||
|
continue
|
||||||
|
if not is_var:
|
||||||
|
if line == 'info messages:\n':
|
||||||
|
info_messages = True
|
||||||
|
continue
|
||||||
|
if not info_messages:
|
||||||
|
continue
|
||||||
if id in line:
|
if id in line:
|
||||||
if (' ' + function_name + ' ') in line:
|
if (' ' + function_name + ' ') in line:
|
||||||
if url:
|
if url:
|
||||||
|
@ -1115,6 +1135,13 @@ class HttpClientThread(Thread):
|
||||||
function_name = url[len('/check_library-'):]
|
function_name = url[len('/check_library-'):]
|
||||||
text = check_library_function_name(self.infoPath, function_name)
|
text = check_library_function_name(self.infoPath, function_name)
|
||||||
httpGetResponse(self.connection, text, 'text/plain')
|
httpGetResponse(self.connection, text, 'text/plain')
|
||||||
|
elif url == '/value_flow_bailout_incomplete_var.html':
|
||||||
|
text = check_library_report(self.resultPath, message_id='valueFlowBailoutIncompleteVar')
|
||||||
|
httpGetResponse(self.connection, text, 'text/html')
|
||||||
|
elif url.startswith('/incomplete_var-'):
|
||||||
|
var_name = url[len('/incomplete_var-'):]
|
||||||
|
text = check_library_function_name(self.resultPath, var_name, True)
|
||||||
|
httpGetResponse(self.connection, text, 'text/plain')
|
||||||
else:
|
else:
|
||||||
filename = resultPath + url
|
filename = resultPath + url
|
||||||
if not os.path.isfile(filename):
|
if not os.path.isfile(filename):
|
||||||
|
|
|
@ -16,7 +16,7 @@ import copy
|
||||||
# Version scheme (MAJOR.MINOR.PATCH) should orientate on "Semantic Versioning" https://semver.org/
|
# Version scheme (MAJOR.MINOR.PATCH) should orientate on "Semantic Versioning" https://semver.org/
|
||||||
# Every change in this script should result in increasing the version number accordingly (exceptions may be cosmetic
|
# Every change in this script should result in increasing the version number accordingly (exceptions may be cosmetic
|
||||||
# changes)
|
# changes)
|
||||||
CLIENT_VERSION = "1.3.47"
|
CLIENT_VERSION = "1.3.48"
|
||||||
|
|
||||||
# Timeout for analysis with Cppcheck in seconds
|
# Timeout for analysis with Cppcheck in seconds
|
||||||
CPPCHECK_TIMEOUT = 30 * 60
|
CPPCHECK_TIMEOUT = 30 * 60
|
||||||
|
@ -443,7 +443,7 @@ def scan_package(cppcheck_path, source_path, libraries, capture_callstack=True):
|
||||||
# TODO: remove missingInclude disabling when it no longer is implied by --enable=information
|
# TODO: remove missingInclude disabling when it no longer is implied by --enable=information
|
||||||
# Reference for GNU C: https://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html
|
# Reference for GNU C: https://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html
|
||||||
options = libs + ' --showtime=top5 --check-library --inconclusive --enable=style,information --inline-suppr --disable=missingInclude --suppress=unmatchedSuppression --template=daca2'
|
options = libs + ' --showtime=top5 --check-library --inconclusive --enable=style,information --inline-suppr --disable=missingInclude --suppress=unmatchedSuppression --template=daca2'
|
||||||
options += ' --debug-warnings --suppress=autoNoType --suppress=valueFlowBailout --suppress=bailoutUninitVar --suppress=symbolDatabaseWarning --suppress=valueFlowBailoutIncompleteVar'
|
options += ' --debug-warnings --suppress=autoNoType --suppress=valueFlowBailout --suppress=bailoutUninitVar --suppress=symbolDatabaseWarning'
|
||||||
options += ' -D__GNUC__ --platform=unix64'
|
options += ' -D__GNUC__ --platform=unix64'
|
||||||
options_rp = options + ' -rp={}'.format(dir_to_scan)
|
options_rp = options + ' -rp={}'.format(dir_to_scan)
|
||||||
if __make_cmd == 'msbuild.exe':
|
if __make_cmd == 'msbuild.exe':
|
||||||
|
|
Loading…
Reference in New Issue