xref: /aosp_15_r20/system/chre/tools/find_improper_target_platform_files.py (revision 84e339476a462649f82315436d70fd732297a399)
1"""Finds header files in target_platform directories that should not be
2
3Some platform implementations have improperly used target_platform when they
4should instead use platform/<platform_name>. This script helps identify those
5files.
6
7Example usage:
8
9  python find_improper_target_platform_files.py -p ../platform -c ../platform/include
10"""
11import argparse
12import os
13import sys
14
15def find_target_platform_files(directories):
16  """
17  Lists all files recursively in the given directories and filters to those with
18  "target_platform" in their path.
19
20  Args:
21    directories: A list of directories to search.
22
23  Returns:
24    A list of file paths that contain "target_platform" in their path.
25  """
26  target_files = []
27  for directory in directories:
28    for root, _, files in os.walk(directory):
29      for file in files:
30        file_path = os.path.join(root, file)
31        if "target_platform" in file_path:
32          target_files.append(file_path)
33  return target_files
34
35def find_unincluded_files(target_files, include_directories):
36  """
37  Flags target_platform files that are not included in any C/C++ #include
38  statements within files in the include_directories.
39
40  Args:
41    target_files: A list of file paths to check.
42    include_directories: A list of directories containing files with
43                         #include statements.
44
45  Returns:
46    A list of target_platform file paths that are not included.
47  """
48  unincluded_files = []
49  included_files = set()
50
51  for directory in include_directories:
52    for root, _, files in os.walk(directory):
53      for file in files:
54        file_path = os.path.join(root, file)
55        try:
56          with open(file_path, "r") as f:
57            for line in f:
58              if line.startswith("#include") and "target_platform" in line:
59                # Extract the included file name, accounting for variations in
60                # include syntax (e.g., quotes vs. angle brackets)
61                included_file = line.split()[1].strip('"<>')
62                included_files.add(included_file)
63        except UnicodeDecodeError:
64          # Skip non-text files
65          continue
66
67  print(f"target_platform files referenced in {include_directories}:")
68  for file in sorted(included_files):
69    print(f"  {file}")
70
71
72  for target_file in target_files:
73    target_file_name = "target_platform/" + os.path.basename(target_file)
74    found = False
75    for included_file in included_files:
76      if included_file.endswith(target_file_name):
77        found = True
78        break
79    if not found:
80      unincluded_files.append(target_file)
81
82  return unincluded_files
83
84if __name__ == "__main__":
85  parser = argparse.ArgumentParser(description="Find files in target_platform directories which are not included from common code.")
86  parser.add_argument("-p", "--platform", nargs="+", required=True, help="Directories containing target_platform subdirectories")
87  parser.add_argument("-c", "--common", nargs="+", required=True, help="Directories containing facades to platform code - all target_platform headers must appear in an #include statement in a file here")
88  args = parser.parse_args()
89
90  target_directories = args.platform
91  include_directories = args.common
92
93  target_files = find_target_platform_files(target_directories)
94  unincluded_files = find_unincluded_files(target_files, include_directories)
95
96  if len(unincluded_files):
97    print("\nThe following target_platform files do not appear in the list above:")
98    for file in sorted(unincluded_files):
99      print(f"  {file}")
100  else:
101    print("All target_platform files are included.")
102