Improvements to check_typed_item_calls.py

This commit is contained in:
Martin Mathieson 2022-01-19 17:14:59 +00:00
parent 3e2c79d924
commit 73b94e7aef
1 changed files with 48 additions and 16 deletions

View File

@ -52,34 +52,66 @@ class Call:
# A check for a particular API function.
class APICheck:
def __init__(self, fun_name, allowed_types):
def __init__(self, fun_name, allowed_types, positive_length=False):
self.fun_name = fun_name
self.allowed_types = allowed_types
self.positive_length = positive_length
self.calls = []
if fun_name.startswith('ptvcursor'):
# RE captures function name + 1st 2 args (always ptvc + hfindex)
self.p = re.compile('.*' + self.fun_name + '\(([a-zA-Z0-9_]+),\s*([a-zA-Z0-9_]+)')
elif fun_name.find('add_bitmask') == -1:
# RE captures function name + 1st 2 args (always tree + hfindex)
self.p = re.compile('.*' + self.fun_name + '\(([a-zA-Z0-9_]+),\s*([a-zA-Z0-9_]+)')
# Normal case.
# RE captures function name + 1st 2 args (always tree + hfindex + length)
self.p = re.compile('.*' + self.fun_name + '\(([a-zA-Z0-9_]+),\s*([a-zA-Z0-9_]+),\s*[a-zA-Z0-9_]+,\s*[a-zA-Z0-9_]+,\s*([a-zA-Z0-9_]+)')
else:
# _add_bitmask functions.
# RE captures function name + 1st + 4th args (always tree + hfindex)
self.p = re.compile('.*' + self.fun_name + '\(([a-zA-Z0-9_]+),\s*[a-zA-Z0-9_]+,\s*[a-zA-Z0-9_]+,\s*([a-zA-Z0-9_]+)')
self.file = None
def find_calls(self, file):
self.file = file
self.calls = []
with open(file, 'r') as f:
for line_number, line in enumerate(f, start=1):
m = self.p.match(line)
if m:
self.calls.append(Call(m.group(2), line_number=line_number))
contents = f.read()
lines = contents.splitlines()
total_lines = len(lines)
line_number = 1
for line in lines:
# Want to check this, and next few lines
to_check = lines[line_number-1]
# Nothing to check if function name isn't in it
if to_check.find(self.fun_name) != -1:
# Ok, add the next file lines before trying RE
for i in range(1, 4):
if line_number+i < total_lines:
to_check += lines[line_number-1+i]
m = self.p.match(to_check)
if m:
# Add call. We have length if re had 3 groups.
num_groups = self.p.groups
self.calls.append(Call(m.group(2),
line_number=line_number,
length=(m.group(3) if (num_groups==3) else None)))
line_number += 1
def check_against_items(self, items):
global errors_found
for call in self.calls:
if self.positive_length and call.length != None:
if call.length != -1 and call.length <= 0:
print('Error: ' + self.fun_name + '(.., ' + call.hf_name + ', ...) called at ' +
self.file + ':' + str(call.line_number) +
' with length ' + str(call.length) + ' - must be > 0 or -1')
# Inc global count of issues found.
errors_found += 1
if call.hf_name in items:
if not items[call.hf_name].item_type in self.allowed_types:
# Report this issue.
@ -88,7 +120,6 @@ class APICheck:
' with type ' + items[call.hf_name].item_type)
print(' (allowed types are', self.allowed_types, ')\n')
# Inc global count of issues found.
global errors_found
errors_found += 1
@ -139,6 +170,7 @@ class ProtoTreeAddItemCheck(APICheck):
with open(file, 'r') as f:
# TODO: would be better to just iterate over those found in whole file,
# but extra effort would be needed to still know line number.
# TODO: See what APICheck does above..
for line_number, line in enumerate(f, start=1):
m = self.p.match(line)
if m:
@ -389,15 +421,15 @@ class Item:
# These are APIs in proto.c that check a set of types at runtime and can print '.. is not of type ..' to the console
# if the type is not suitable.
apiChecks = []
apiChecks.append(APICheck('proto_tree_add_item_ret_uint', { 'FT_CHAR', 'FT_UINT8', 'FT_UINT16', 'FT_UINT24', 'FT_UINT32'}))
apiChecks.append(APICheck('proto_tree_add_item_ret_uint', { 'FT_CHAR', 'FT_UINT8', 'FT_UINT16', 'FT_UINT24', 'FT_UINT32'}, positive_length=True))
apiChecks.append(APICheck('proto_tree_add_item_ret_int', { 'FT_INT8', 'FT_INT16', 'FT_INT24', 'FT_INT32'}))
apiChecks.append(APICheck('ptvcursor_add_ret_uint', { 'FT_CHAR', 'FT_UINT8', 'FT_UINT16', 'FT_UINT24', 'FT_UINT32'}))
apiChecks.append(APICheck('ptvcursor_add_ret_int', { 'FT_INT8', 'FT_INT16', 'FT_INT24', 'FT_INT32'}))
apiChecks.append(APICheck('ptvcursor_add_ret_uint', { 'FT_CHAR', 'FT_UINT8', 'FT_UINT16', 'FT_UINT24', 'FT_UINT32'}, positive_length=True))
apiChecks.append(APICheck('ptvcursor_add_ret_int', { 'FT_INT8', 'FT_INT16', 'FT_INT24', 'FT_INT32'}, positive_length=True))
apiChecks.append(APICheck('ptvcursor_add_ret_string', { 'FT_STRING', 'FT_STRINGZ', 'FT_UINT_STRING', 'FT_STRINGZPAD', 'FT_STRINGZTRUNC'}))
apiChecks.append(APICheck('ptvcursor_add_ret_boolean', { 'FT_BOOLEAN'}))
apiChecks.append(APICheck('proto_tree_add_item_ret_uint64', { 'FT_UINT40', 'FT_UINT48', 'FT_UINT56', 'FT_UINT64'}))
apiChecks.append(APICheck('proto_tree_add_item_ret_int64', { 'FT_INT40', 'FT_INT48', 'FT_INT56', 'FT_INT64'}))
apiChecks.append(APICheck('proto_tree_add_item_ret_boolean', { 'FT_BOOLEAN'}))
apiChecks.append(APICheck('ptvcursor_add_ret_boolean', { 'FT_BOOLEAN'}, positive_length=True))
apiChecks.append(APICheck('proto_tree_add_item_ret_uint64', { 'FT_UINT40', 'FT_UINT48', 'FT_UINT56', 'FT_UINT64'}, positive_length=True))
apiChecks.append(APICheck('proto_tree_add_item_ret_int64', { 'FT_INT40', 'FT_INT48', 'FT_INT56', 'FT_INT64'}, positive_length=True))
apiChecks.append(APICheck('proto_tree_add_item_ret_boolean', { 'FT_BOOLEAN'}, positive_length=True))
apiChecks.append(APICheck('proto_tree_add_item_ret_string_and_length', { 'FT_STRING', 'FT_STRINGZ', 'FT_UINT_STRING', 'FT_STRINGZPAD', 'FT_STRINGZTRUNC'}))
apiChecks.append(APICheck('proto_tree_add_item_ret_display_string_and_length', { 'FT_STRING', 'FT_STRINGZ', 'FT_UINT_STRING',
'FT_STRINGZPAD', 'FT_STRINGZTRUNC', 'FT_BYTES', 'FT_UINT_BYTES'}))
@ -435,6 +467,7 @@ apiChecks.append(APICheck('proto_tree_add_ascii_7bits_item', { 'FT_STRING'}))
apiChecks.append(APICheck('proto_tree_add_checksum', { 'FT_UINT8', 'FT_UINT16', 'FT_UINT24', 'FT_UINT32'}))
apiChecks.append(APICheck('proto_tree_add_int64_bits_format_value', { 'FT_INT40', 'FT_INT48', 'FT_INT56', 'FT_INT64'}))
# TODO: add proto_tree_add_bytes_item, proto_tree_add_time_item ?
bitmask_types = { 'FT_CHAR', 'FT_UINT8', 'FT_UINT16', 'FT_UINT24', 'FT_UINT32',
'FT_INT8', 'FT_INT16', 'FT_INT24', 'FT_INT32',
@ -488,7 +521,6 @@ def isGeneratedFile(filename):
line.find('This filter was automatically generated') != -1 or
line.find('This file is auto generated, do not edit!') != -1):
f_read.close()
return True
lines_tested = lines_tested + 1