• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #!/usr/bin/python2
2 #
3 # Copyright 2019 Google Inc.
4 #
5 # Use of this source code is governed by a BSD-style license that can be
6 # found in the LICENSE file.
7 
8 import StringIO
9 import argparse
10 import os
11 import sys
12 
13 parser = argparse.ArgumentParser()
14 parser.add_argument('-n', '--dry-run', action='store_true',
15                     help='Just check there is nothing to rewrite.')
16 parser.add_argument('sources', nargs='*',
17                     help='Source files to rewrite, or all if empty.')
18 args = parser.parse_args()
19 
20 roots = [
21     'bench',
22     'dm',
23     'docs',
24     'example',
25     'experimental',
26     'fuzz',
27     'gm',
28     'include',
29     'modules',
30     'platform_tools/android/apps',
31     'samplecode',
32     'src',
33     'tests',
34     'third_party/etc1',
35     'third_party/gif',
36     'tools'
37   ]
38 
39 # Don't count our local Vulkan headers as Skia headers;
40 # we don't want #include <vulkan/vulkan_foo.h> rewritten to point to them.
41 blacklist = ['include/third_party/vulkan']
42 
43 assert '/' in [os.sep, os.altsep]
44 def fix_path(p):
45   return p.replace(os.sep, os.altsep) if os.altsep else p
46 
47 # Map short name -> absolute path for all Skia headers.
48 headers = {}
49 for root in roots:
50   for path, _, files in os.walk(root):
51     if not any(snippet in fix_path(path) for snippet in blacklist):
52       for file_name in files:
53         if file_name.endswith('.h'):
54           if file_name in headers:
55             print path, file_name, headers[file_name]
56           assert file_name not in headers
57           headers[file_name] = os.path.abspath(os.path.join(path, file_name))
58 
59 def to_rewrite():
60   if args.sources:
61     for path in args.sources:
62       yield path
63   else:
64     for root in roots:
65       for path, _, files in os.walk(root):
66         for file_name in files:
67           yield os.path.join(path, file_name)
68 
69 # Rewrite any #includes relative to Skia's top-level directory.
70 need_rewriting = []
71 for file_path in to_rewrite():
72   if 'generated' in file_path:
73     continue
74   if (file_path.endswith('.h') or
75       file_path.endswith('.c') or
76       file_path.endswith('.m') or
77       file_path.endswith('.mm') or
78       file_path.endswith('.inc') or
79       file_path.endswith('.fp') or
80       file_path.endswith('.cc') or
81       file_path.endswith('.cpp')):
82     # Read the whole file into memory.
83     lines = open(file_path).readlines()
84 
85     # Write it back out again line by line with substitutions for #includes.
86     output = StringIO.StringIO() if args.dry_run else open(file_path, 'wb')
87 
88     includes = []
89     for line in lines:
90       parts = line.replace('<', '"').replace('>', '"').split('"')
91       if (len(parts) == 3
92           and '#' in parts[0]
93           and 'include' in parts[0]
94           and os.path.basename(parts[1]) in headers):
95         header = fix_path(os.path.relpath(headers[os.path.basename(parts[1])], '.'))
96         includes.append(parts[0] + '"%s"' % header + parts[2])
97       else:
98         for inc in sorted(includes):
99           output.write(inc.strip('\n') + '\n')
100         includes = []
101         output.write(line.strip('\n') + '\n')
102 
103     if args.dry_run and output.getvalue() != open(file_path).read():
104       need_rewriting.append(file_path)
105       rc = 1
106     output.close()
107 
108 if need_rewriting:
109   print 'Some files need rewritten #includes:'
110   for path in need_rewriting:
111     print '\t' + path
112   print 'To do this automatically, run'
113   print 'python tools/rewrite_includes.py ' + ' '.join(need_rewriting)
114   sys.exit(1)
115