1 #!/usr/bin/python 2 3 ''' 4 Copyright 2014 Google Inc. 5 6 Use of this source code is governed by a BSD-style license that can be 7 found in the LICENSE file. 8 ''' 9 10 import os 11 import optparse 12 import posixpath 13 import re 14 15 16 def is_ignored(full_path, ignore_list): 17 for ignore_path in ignore_list: 18 if re.search(ignore_path, full_path, re.I): 19 return True 20 return False 21 22 23 def find_header_files(include_dirs, ignore_list): 24 """Return a list of all '.h' files in top_dir. 25 26 Args: 27 include_dirs: Paths to the directories within which to recursively search 28 for files ending in '.h' 29 ignore_list: Paths to both files and directories that are to be excluded 30 from the search for headers 31 32 Returns: 33 A list of all the files inside include_dirs that end in '.h', relative to 34 their respective include_dir that are not explicitly ignored. 35 """ 36 headers = [] 37 for top_dir in include_dirs: 38 for filename in os.listdir(top_dir): 39 full_path = posixpath.join(top_dir, filename) 40 if is_ignored(full_path, ignore_list): 41 continue 42 elif os.path.isdir(full_path): 43 nested_headers = find_header_files([full_path], ignore_list) 44 for nested_header in nested_headers: 45 headers.append(os.path.join(filename, nested_header)) 46 elif filename.endswith('.h'): 47 headers.append(filename) 48 return headers 49 50 51 def GenerateIncludeCPP(output_file, include_dirs, ignore_list): 52 headers = find_header_files(include_dirs, ignore_list) 53 54 # Emit resulting source file. 55 with open(os.path.join(os.getcwd(), output_file), "w+") as output: 56 for header in headers: 57 output.write("#include <%s>\n" % header) 58 59 60 def main(): 61 parser = optparse.OptionParser() 62 parser.add_option("--ignore", action="store", type="string", dest="ignore", 63 help="file to write the processed sources array to.") 64 parser.set_usage("""generate_include_cpp out.cpp include_dir 65 out.cpp: C++ code to be generated. 66 include_dirs: directories to traverse for include files""") 67 (options, args) = parser.parse_args() 68 69 # The MSVS gyp generator uses windows path separators so we intercept those 70 # strings and normalize them to our expected posix representation 71 include_dirs = [] 72 for include_dir in args[1:]: 73 include_dirs.append(include_dir.replace("\\", "/")) 74 ignore_list = options.ignore.replace("\\", "/") 75 76 # We can strip off the relative portion of the path to ensure that when we 77 # compare for regex matches we don't fail based on relative path depth 78 ignore_list = ignore_list.replace("../", "") 79 80 GenerateIncludeCPP(args[0], include_dirs, ignore_list.split()) 81 82 83 if __name__ == "__main__": 84 main() 85