Commit fc2cb22e authored by Masahiro Yamada's avatar Masahiro Yamada

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.
Signed-off-by: default avatarMasahiro Yamada <masahiroy@kernel.org>
Reviewed-by: default avatarNick Desaulniers <ndesaulniers@google.com>
parent 6fca36f1
...@@ -33,6 +33,7 @@ def parse_arguments(): ...@@ -33,6 +33,7 @@ def parse_arguments():
log_level: A logging level to filter log output. log_level: A logging level to filter log output.
directory: The work directory where the objects were built. directory: The work directory where the objects were built.
output: Where to write the compile-commands JSON file. output: Where to write the compile-commands JSON file.
paths: The list of directories to handle to find .cmd files.
""" """
usage = 'Creates a compile_commands.json database from kernel .cmd files' usage = 'Creates a compile_commands.json database from kernel .cmd files'
parser = argparse.ArgumentParser(description=usage) parser = argparse.ArgumentParser(description=usage)
...@@ -56,7 +57,28 @@ def parse_arguments(): ...@@ -56,7 +57,28 @@ def parse_arguments():
return (args.log_level, return (args.log_level,
os.path.abspath(args.directory), os.path.abspath(args.directory),
args.output) args.output,
[args.directory])
def cmdfiles_in_dir(directory):
"""Generate the iterator of .cmd files found under the directory.
Walk under the given directory, and yield every .cmd file found.
Args:
directory: The directory to search for .cmd files.
Yields:
The path to a .cmd file.
"""
filename_matcher = re.compile(_FILENAME_PATTERN)
for dirpath, _, filenames in os.walk(directory):
for filename in filenames:
if filename_matcher.match(filename):
yield os.path.join(dirpath, filename)
def process_line(root_directory, command_prefix, file_path): def process_line(root_directory, command_prefix, file_path):
...@@ -95,31 +117,29 @@ def process_line(root_directory, command_prefix, file_path): ...@@ -95,31 +117,29 @@ def process_line(root_directory, command_prefix, file_path):
def main(): def main():
"""Walks through the directory and finds and parses .cmd files.""" """Walks through the directory and finds and parses .cmd files."""
log_level, directory, output = parse_arguments() log_level, directory, output, paths = parse_arguments()
level = getattr(logging, log_level) level = getattr(logging, log_level)
logging.basicConfig(format='%(levelname)s: %(message)s', level=level) logging.basicConfig(format='%(levelname)s: %(message)s', level=level)
filename_matcher = re.compile(_FILENAME_PATTERN)
line_matcher = re.compile(_LINE_PATTERN) line_matcher = re.compile(_LINE_PATTERN)
compile_commands = [] compile_commands = []
for dirpath, _, filenames in os.walk(directory):
for filename in filenames:
if not filename_matcher.match(filename):
continue
filepath = os.path.join(dirpath, filename)
with open(filepath, 'rt') as f: for path in paths:
cmdfiles = cmdfiles_in_dir(path)
for cmdfile in cmdfiles:
with open(cmdfile, 'rt') as f:
result = line_matcher.match(f.readline()) result = line_matcher.match(f.readline())
if result: if result:
try: try:
entry = process_line(directory, entry = process_line(directory, result.group(1),
result.group(1), result.group(2)) result.group(2))
compile_commands.append(entry) compile_commands.append(entry)
except ValueError as err: except ValueError as err:
logging.info('Could not add line from %s: %s', logging.info('Could not add line from %s: %s',
filepath, err) cmdfile, err)
with open(output, 'wt') as f: with open(output, 'wt') as f:
json.dump(compile_commands, f, indent=2, sort_keys=True) json.dump(compile_commands, f, indent=2, sort_keys=True)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment