blob: 843f56addcb50390b45379cf3876ff6563af1510 [file] [log] [blame]
#!/usr/bin/env python
# Copyright 2018 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Merges headers from two different paths, surrounding differing blocks with
macro guards that can be specified via command line argument.
Usage:
python merge_headers.py --def1=__aarch64__ --def2=__x86_64__ out/arm64 out/x64
"""
import argparse
import difflib
import filecmp
import os
import shutil
import sys
def copyfile(src_a, src_b, dst, def_a=None, def_b=None):
if filecmp.cmp(src_a, src_b):
print 'Copy: %s' % dst
shutil.copyfile(src_a, dst)
return
with open(src_a, 'r') as f:
a = f.readlines()
with open(src_b, 'r') as f:
b = f.readlines()
s = difflib.SequenceMatcher(None, a, b)
out = []
blocks = s.get_matching_blocks()
for i in range(0, len(blocks) - 1):
out.extend(a[blocks[i].a:blocks[i].a + blocks[i].size])
diff_a = a[blocks[i].a + blocks[i].size:blocks[i + 1].a]
if diff_a and def_a:
out.extend(['#ifdef %s\n' % def_a] + diff_a + ['#endif\n'])
diff_b = b[blocks[i].b + blocks[i].size:blocks[i + 1].b]
if diff_b and def_b:
out.extend(['#ifdef %s\n' % def_b] + diff_b + ['#endif\n'])
with open(dst, 'w') as f:
print 'Merge: %s' % dst
f.writelines(out)
def copytree(src_a, src_b, dst, def_a=None, def_b=None):
names = os.listdir(src_a)
if not os.path.isdir(dst):
os.makedirs(dst)
for name in names:
srcname_a = os.path.join(src_a, name)
srcname_b = os.path.join(src_b, name)
dstname = os.path.join(dst, name)
try:
if os.path.islink(srcname_a):
linkto = os.readlink(srcname_a)
os.symlink(linkto, dstname)
elif os.path.isdir(srcname_a):
copytree(srcname_a, srcname_b, dstname, def_a, def_b)
else:
copyfile(srcname_a, srcname_b, dstname, def_a, def_b)
except Exception:
shutil.rmtree(dst, ignore_errors=True)
raise
def main():
parser = argparse.ArgumentParser()
parser.add_argument(
'-o', '--out', default=os.getcwd(), help='destination path')
parser.add_argument('--def1', help='define value for first path')
parser.add_argument('--def2', help='define value for second path')
parser.add_argument('path1', help='first path')
parser.add_argument('path2', help='second path')
args = parser.parse_args()
copytree(args.path1, args.path2, args.out, args.def1, args.def2)
return 0
if __name__ == '__main__':
sys.exit(main())