Merge pull request #6938 from aditya-deshpande-arm/check-names-exclusions

check_names.py: Compare identifiers in excluded files against symbols parsed by nm
This commit is contained in:
Manuel Pégourié-Gonnard 2023-01-30 09:21:58 +01:00 committed by GitHub
commit e28397a376
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 64 additions and 20 deletions

View file

@ -268,13 +268,13 @@ class CodeParser():
"3rdparty/everest/include/everest/everest.h", "3rdparty/everest/include/everest/everest.h",
"3rdparty/everest/include/everest/x25519.h" "3rdparty/everest/include/everest/x25519.h"
]) ])
identifiers = self.parse_identifiers([ identifiers, excluded_identifiers = self.parse_identifiers([
"include/mbedtls/*.h", "include/mbedtls/*.h",
"include/psa/*.h", "include/psa/*.h",
"library/*.h", "library/*.h",
"3rdparty/everest/include/everest/everest.h", "3rdparty/everest/include/everest/everest.h",
"3rdparty/everest/include/everest/x25519.h" "3rdparty/everest/include/everest/x25519.h"
]) ], ["3rdparty/p256-m/p256-m/p256-m.h"])
mbed_psa_words = self.parse_mbed_psa_words([ mbed_psa_words = self.parse_mbed_psa_words([
"include/mbedtls/*.h", "include/mbedtls/*.h",
"include/psa/*.h", "include/psa/*.h",
@ -311,6 +311,7 @@ class CodeParser():
"private_macros": all_macros["private"], "private_macros": all_macros["private"],
"enum_consts": enum_consts, "enum_consts": enum_consts,
"identifiers": identifiers, "identifiers": identifiers,
"excluded_identifiers": excluded_identifiers,
"symbols": symbols, "symbols": symbols,
"mbed_psa_words": mbed_psa_words "mbed_psa_words": mbed_psa_words
} }
@ -324,12 +325,42 @@ class CodeParser():
return True return True
return False return False
def get_files(self, include_wildcards, exclude_wildcards): def get_all_files(self, include_wildcards, exclude_wildcards):
""" """
Get all files that match any of the UNIX-style wildcards. While the Get all files that match any of the included UNIX-style wildcards
check_names script is designed only for use on UNIX/macOS (due to nm), and filter them into included and excluded lists.
this function alone would work fine on Windows even with forward slashes While the check_names script is designed only for use on UNIX/macOS
in the wildcard. (due to nm), this function alone will work fine on Windows even with
forward slashes in the wildcard.
Args:
* include_wildcards: a List of shell-style wildcards to match filepaths.
* exclude_wildcards: a List of shell-style wildcards to exclude.
Returns:
* inc_files: A List of relative filepaths for included files.
* exc_files: A List of relative filepaths for excluded files.
"""
accumulator = set()
all_wildcards = include_wildcards + (exclude_wildcards or [])
for wildcard in all_wildcards:
accumulator = accumulator.union(glob.iglob(wildcard))
inc_files = []
exc_files = []
for path in accumulator:
if self.is_file_excluded(path, exclude_wildcards):
exc_files.append(path)
else:
inc_files.append(path)
return (inc_files, exc_files)
def get_included_files(self, include_wildcards, exclude_wildcards):
"""
Get all files that match any of the included UNIX-style wildcards.
While the check_names script is designed only for use on UNIX/macOS
(due to nm), this function alone will work fine on Windows even with
forward slashes in the wildcard.
Args: Args:
* include_wildcards: a List of shell-style wildcards to match filepaths. * include_wildcards: a List of shell-style wildcards to match filepaths.
@ -360,7 +391,7 @@ class CodeParser():
"asm", "inline", "EMIT", "_CRT_SECURE_NO_DEPRECATE", "MULADDC_" "asm", "inline", "EMIT", "_CRT_SECURE_NO_DEPRECATE", "MULADDC_"
) )
files = self.get_files(include, exclude) files = self.get_included_files(include, exclude)
self.log.debug("Looking for macros in {} files".format(len(files))) self.log.debug("Looking for macros in {} files".format(len(files)))
macros = [] macros = []
@ -395,7 +426,7 @@ class CodeParser():
mbed_regex = re.compile(r"\b(MBED.+?|PSA)_[A-Z0-9_]*") mbed_regex = re.compile(r"\b(MBED.+?|PSA)_[A-Z0-9_]*")
exclusions = re.compile(r"// *no-check-names|#error") exclusions = re.compile(r"// *no-check-names|#error")
files = self.get_files(include, exclude) files = self.get_included_files(include, exclude)
self.log.debug( self.log.debug(
"Looking for MBED|PSA words in {} files" "Looking for MBED|PSA words in {} files"
.format(len(files)) .format(len(files))
@ -428,7 +459,7 @@ class CodeParser():
Returns a List of Match objects for the findings. Returns a List of Match objects for the findings.
""" """
files = self.get_files(include, exclude) files = self.get_included_files(include, exclude)
self.log.debug("Looking for enum consts in {} files".format(len(files))) self.log.debug("Looking for enum consts in {} files".format(len(files)))
# Emulate a finite state machine to parse enum declarations. # Emulate a finite state machine to parse enum declarations.
@ -611,23 +642,34 @@ class CodeParser():
""" """
Parse all lines of a header where a function/enum/struct/union/typedef Parse all lines of a header where a function/enum/struct/union/typedef
identifier is declared, based on some regex and heuristics. Highly identifier is declared, based on some regex and heuristics. Highly
dependent on formatting style. dependent on formatting style. Identifiers in excluded files are still
parsed
Args: Args:
* include: A List of glob expressions to look for files through. * include: A List of glob expressions to look for files through.
* exclude: A List of glob expressions for excluding files. * exclude: A List of glob expressions for excluding files.
Returns a List of Match objects with identifiers. Returns: a Tuple of two Lists of Match objects with identifiers.
* included_identifiers: A List of Match objects with identifiers from
included files.
* excluded_identifiers: A List of Match objects with identifiers from
excluded files.
""" """
files = self.get_files(include, exclude) included_files, excluded_files = \
self.log.debug("Looking for identifiers in {} files".format(len(files))) self.get_all_files(include, exclude)
identifiers = [] self.log.debug("Looking for included identifiers in {} files".format \
for header_file in files: (len(included_files)))
self.parse_identifiers_in_file(header_file, identifiers)
return identifiers included_identifiers = []
excluded_identifiers = []
for header_file in included_files:
self.parse_identifiers_in_file(header_file, included_identifiers)
for header_file in excluded_files:
self.parse_identifiers_in_file(header_file, excluded_identifiers)
return (included_identifiers, excluded_identifiers)
def parse_symbols(self): def parse_symbols(self):
""" """
@ -789,10 +831,12 @@ class NameChecker():
Returns the number of problems that need fixing. Returns the number of problems that need fixing.
""" """
problems = [] problems = []
all_identifiers = self.parse_result["identifiers"] + \
self.parse_result["excluded_identifiers"]
for symbol in self.parse_result["symbols"]: for symbol in self.parse_result["symbols"]:
found_symbol_declared = False found_symbol_declared = False
for identifier_match in self.parse_result["identifiers"]: for identifier_match in all_identifiers:
if symbol == identifier_match.name: if symbol == identifier_match.name:
found_symbol_declared = True found_symbol_declared = True
break break

View file

@ -46,7 +46,7 @@ def main():
result = name_check.parse_identifiers([ result = name_check.parse_identifiers([
"include/mbedtls/*_internal.h", "include/mbedtls/*_internal.h",
"library/*.h" "library/*.h"
]) ])[0]
result.sort(key=lambda x: x.name) result.sort(key=lambda x: x.name)
identifiers = ["{}\n".format(match.name) for match in result] identifiers = ["{}\n".format(match.name) for match in result]