Home | History | Annotate | Download | only in tools
      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