History

gen_compile_commands: move directory walk to a generator function

Currently, this script walks under the specified directory (default to the current directory), then parses all .cmd files found. Split it into a separate helper function because the next commit will add more helpers to pick up .cmd files associated with given file(s). There is no point to build and return a huge list at once. I used a generator so it works in the for-loop with less memory.

Masahiro Yamada committed 6 years ago

Commit fc2cb221 parent 6fca36f1 file · +32 −12Browse files

Showing the changes to scripts (1 of 1 file). Show all

Unified · Split

scripts/gen_compile_commands.py+32−12
@@ -33,6 +33,7 @@ def parse_arguments(): · 32 unmodified lines
33 log_level: A logging level to filter log output.33 log_level: A logging level to filter log output.
34 directory: The work directory where the objects were built.34 directory: The work directory where the objects were built.
35 output: Where to write the compile-commands JSON file.35 output: Where to write the compile-commands JSON file.
36 paths: The list of directories to handle to find .cmd files.
36 """37 """
37 usage = 'Creates a compile_commands.json database from kernel .cmd files'38 usage = 'Creates a compile_commands.json database from kernel .cmd files'
38 parser = argparse.ArgumentParser(description=usage)39 parser = argparse.ArgumentParser(description=usage)
@@ -56,7 +57,28 @@ def parse_arguments(): · 17 unmodified lines
56 57
57 return (args.log_level,58 return (args.log_level,
58 os.path.abspath(args.directory),59 os.path.abspath(args.directory),
59 args.output)60 args.output,
61 [args.directory])
62
63
64def cmdfiles_in_dir(directory):
65 """Generate the iterator of .cmd files found under the directory.
66
67 Walk under the given directory, and yield every .cmd file found.
68
69 Args:
70 directory: The directory to search for .cmd files.
71
72 Yields:
73 The path to a .cmd file.
74 """
75
76 filename_matcher = re.compile(_FILENAME_PATTERN)
77
78 for dirpath, _, filenames in os.walk(directory):
79 for filename in filenames:
80 if filename_matcher.match(filename):
81 yield os.path.join(dirpath, filename)
60 82
61 83
62def process_line(root_directory, command_prefix, file_path):84def process_line(root_directory, command_prefix, file_path):
@@ -95,31 +117,29 @@ def process_line(root_directory, command_prefix, file_path): · 32 unmodified lines
95 117
96def main():118def main():
97 """Walks through the directory and finds and parses .cmd files."""119 """Walks through the directory and finds and parses .cmd files."""
98 log_level, directory, output = parse_arguments()120 log_level, directory, output, paths = parse_arguments()
99 121
100 level = getattr(logging, log_level)122 level = getattr(logging, log_level)
101 logging.basicConfig(format='%(levelname)s: %(message)s', level=level)123 logging.basicConfig(format='%(levelname)s: %(message)s', level=level)
102 124
103 filename_matcher = re.compile(_FILENAME_PATTERN)
104 line_matcher = re.compile(_LINE_PATTERN)125 line_matcher = re.compile(_LINE_PATTERN)
105 126
106 compile_commands = []127 compile_commands = []
107 for dirpath, _, filenames in os.walk(directory):
108 for filename in filenames:
109 if not filename_matcher.match(filename):
110 continue
111 filepath = os.path.join(dirpath, filename)
112 128
113 with open(filepath, 'rt') as f:129 for path in paths:
130 cmdfiles = cmdfiles_in_dir(path)
131
132 for cmdfile in cmdfiles:
133 with open(cmdfile, 'rt') as f:
114 result = line_matcher.match(f.readline())134 result = line_matcher.match(f.readline())
115 if result:135 if result:
116 try:136 try:
117 entry = process_line(directory,137 entry = process_line(directory, result.group(1),
118 result.group(1), result.group(2))138 result.group(2))
119 compile_commands.append(entry)139 compile_commands.append(entry)
120 except ValueError as err:140 except ValueError as err:
121 logging.info('Could not add line from %s: %s',141 logging.info('Could not add line from %s: %s',
122 filepath, err)142 cmdfile, err)
123 143
124 with open(output, 'wt') as f:144 with open(output, 'wt') as f:
125 json.dump(compile_commands, f, indent=2, sort_keys=True)145 json.dump(compile_commands, f, indent=2, sort_keys=True)