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

Unified · Split

scripts/gen_compile_commands.py+32−12
@@ -33,6 +33,7 @@ def parse_arguments(): · 32 unmodified lines
3333 log_level: A logging level to filter log output.
3434 directory: The work directory where the objects were built.
3535 output: Where to write the compile-commands JSON file.
36+ paths: The list of directories to handle to find .cmd files.
3637 """
3738 usage = 'Creates a compile_commands.json database from kernel .cmd files'
3839 parser = argparse.ArgumentParser(description=usage)
@@ -56,7 +57,28 @@ def parse_arguments(): · 17 unmodified lines
5657
5758 return (args.log_level,
5859 os.path.abspath(args.directory),
59− args.output)
60+ args.output,
61+ [args.directory])
62+
63+
64+def 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)
6082
6183
6284 def process_line(root_directory, command_prefix, file_path):
@@ -95,31 +117,29 @@ def process_line(root_directory, command_prefix, file_path): · 32 unmodified lines
95117
96118 def main():
97119 """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()
99121
100122 level = getattr(logging, log_level)
101123 logging.basicConfig(format='%(levelname)s: %(message)s', level=level)
102124
103− filename_matcher = re.compile(_FILENAME_PATTERN)
104125 line_matcher = re.compile(_LINE_PATTERN)
105126
106127 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)
112128
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:
114134 result = line_matcher.match(f.readline())
115135 if result:
116136 try:
117− entry = process_line(directory,
118− result.group(1), result.group(2))
137+ entry = process_line(directory, result.group(1),
138+ result.group(2))
119139 compile_commands.append(entry)
120140 except ValueError as err:
121141 logging.info('Could not add line from %s: %s',
122− filepath, err)
142+ cmdfile, err)
123143
124144 with open(output, 'wt') as f:
125145 json.dump(compile_commands, f, indent=2, sort_keys=True)