• 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
8import StringIO
9import argparse
10import os
11import sys
12
13parser = argparse.ArgumentParser()
14parser.add_argument('-n', '--dry-run', action='store_true',
15                    help='Just check there is nothing to rewrite.')
16parser.add_argument('sources', nargs='*',
17                    help='Source files to rewrite, or all if empty.')
18args = parser.parse_args()
19
20roots = [
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.
41blacklist = ['include/third_party/vulkan']
42
43assert '/' in [os.sep, os.altsep]
44def 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.
48headers = {}
49for 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
59def 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.
70need_rewriting = []
71for 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
108if 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