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