Skip to content

Commit

Permalink
Update check_names.py so that identifiers in excluded files are still…
Browse files Browse the repository at this point in the history
… compared against the output of nm.

This fixes the issue where excluding a file containing identifiers from checks would cause check_symbols_in_header to fail.

Signed-off-by: Aditya Deshpande <aditya.deshpande@arm.com>
  • Loading branch information
aditya-deshpande-arm committed Jan 25, 2023
1 parent 8431fe0 commit 94375c8
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 23 deletions.
82 changes: 60 additions & 22 deletions tests/scripts/check_names.py
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@ def comprehensive_parse(self):
"3rdparty/everest/include/everest/everest.h",
"3rdparty/everest/include/everest/x25519.h"
])
identifiers = self.parse_identifiers([
identifiers, excluded_identifiers = self.parse_identifiers([
"include/mbedtls/*.h",
"include/psa/*.h",
"library/*.h",
Expand Down Expand Up @@ -302,6 +302,7 @@ def comprehensive_parse(self):
"private_macros": private_macros,
"enum_consts": enum_consts,
"identifiers": identifiers,
"excluded_identifiers": excluded_identifiers,
"symbols": symbols,
"mbed_psa_words": mbed_psa_words
}
Expand All @@ -315,17 +316,43 @@ def is_file_excluded(self, path, exclude_wildcards):
return True
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
check_names script is designed only for use on UNIX/macOS (due to nm),
this function alone would work fine on Windows even with forward slashes
in the wildcard.
Get all files that match any of the included UNIX-style wildcards
and filter them into included and excluded lists.
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:
* 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:
* include_wildcards: a List of shell-style wildcards to match filepaths.
* exclude_wildcards: a List of shell-style wildcards to exclude.
Returns a List of relative filepaths.
"""
accumulator = set()
Expand All @@ -336,6 +363,7 @@ def get_files(self, include_wildcards, exclude_wildcards):
return list(path for path in accumulator
if not self.is_file_excluded(path, exclude_wildcards))


def parse_macros(self, include, exclude=None):
"""
Parse all macros defined by #define preprocessor directives.
Expand All @@ -351,7 +379,7 @@ def parse_macros(self, include, exclude=None):
"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)))

macros = []
Expand Down Expand Up @@ -386,7 +414,7 @@ def parse_mbed_psa_words(self, include, exclude=None):
mbed_regex = re.compile(r"\b(MBED.+?|PSA)_[A-Z0-9_]*")
exclusions = re.compile(r"// *no-check-names|#error")

files = self.get_files(include, exclude)
files = self.get_included_files(include, exclude)
self.log.debug(
"Looking for MBED|PSA words in {} files"
.format(len(files))
Expand Down Expand Up @@ -419,7 +447,7 @@ def parse_enum_consts(self, include, exclude=None):
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)))

# Emulate a finite state machine to parse enum declarations.
Expand Down Expand Up @@ -602,23 +630,32 @@ def parse_identifiers(self, include, exclude=None):
"""
Parse all lines of a header where a function/enum/struct/union/typedef
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:
* include: A List of glob expressions to look for files through.
* 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)
self.log.debug("Looking for identifiers in {} files".format(len(files)))
included_files, excluded_files = \
self.get_all_files(include, exclude)

identifiers = []
for header_file in files:
self.parse_identifiers_in_file(header_file, identifiers)
self.log.debug("Looking for included identifiers in {} files".format \
(len(included_files)))

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 identifiers
return (included_identifiers, excluded_identifiers)

def parse_symbols(self):
"""
Expand Down Expand Up @@ -775,14 +812,15 @@ def check_symbols_declared_in_header(self):
Perform a check that all detected symbols in the library object files
are properly declared in headers.
Assumes parse_names_in_source() was called before this.
Returns the number of problems that need fixing.
"""
problems = []
all_identifiers = self.parse_result["identifiers"] + \
self.parse_result["excluded_identifiers"]

for symbol in self.parse_result["symbols"]:
found_symbol_declared = False
for identifier_match in self.parse_result["identifiers"]:
for identifier_match in all_identifiers:
if symbol == identifier_match.name:
found_symbol_declared = True
break
Expand Down
2 changes: 1 addition & 1 deletion tests/scripts/list_internal_identifiers.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ def main():
result = name_check.parse_identifiers([
"include/mbedtls/*_internal.h",
"library/*.h"
])
])[0]
result.sort(key=lambda x: x.name)

identifiers = ["{}\n".format(match.name) for match in result]
Expand Down

0 comments on commit 94375c8

Please sign in to comment.