| #!/usr/bin/env python3 | |
| """Generate harfbuzz-world.cc from a template and tagged source lists. | |
| Usage: | |
| gen-harfbuzz-world.py OUTPUT SRCDIR TEMPLATE --TAG file1.cc file2.cc --TAG2 ... | |
| Each --TAG starts a new group. The template file has %%TAG%% | |
| placeholders that get replaced with #include lines for that group. | |
| """ | |
| import os, sys, shutil, pathlib | |
| if len(sys.argv) < 4: | |
| sys.exit(__doc__) | |
| OUTPUT = sys.argv[1] | |
| CURRENT_SOURCE_DIR = sys.argv[2] | |
| TEMPLATE = sys.argv[3] | |
| # Parse --TAG file... groups | |
| groups = {} | |
| current_tag = None | |
| for arg in sys.argv[4:]: | |
| if arg.startswith('--'): | |
| current_tag = arg[2:] | |
| groups[current_tag] = [] | |
| elif current_tag is not None: | |
| groups[current_tag].append(arg) | |
| # Build #include lines for each group | |
| def make_includes(files): | |
| seen = set() | |
| lines = [] | |
| for f in sorted(files): | |
| if not f.endswith('.cc'): | |
| continue | |
| rel = pathlib.Path(os.path.relpath(os.path.abspath(f), CURRENT_SOURCE_DIR)).as_posix() | |
| if rel not in seen: | |
| seen.add(rel) | |
| lines.append('#include "{}"'.format(rel)) | |
| return '\n'.join(lines) | |
| # Read template and substitute | |
| with open(TEMPLATE, 'r') as f: | |
| content = f.read() | |
| for tag, files in groups.items(): | |
| placeholder = '%%{}%%'.format(tag) | |
| content = content.replace(placeholder, make_includes(files)) | |
| with open(OUTPUT, 'w') as f: | |
| f.write(content) | |
| # Copy back to source tree if changed | |
| baseline = os.path.join(CURRENT_SOURCE_DIR, os.path.basename(OUTPUT)) | |
| try: | |
| with open(baseline, 'r') as b: | |
| if b.read() == content: | |
| sys.exit(0) | |
| except FileNotFoundError: | |
| pass | |
| try: | |
| shutil.copyfile(OUTPUT, baseline) | |
| except OSError: | |
| import filecmp | |
| if os.path.exists(baseline) and not filecmp.cmp(OUTPUT, baseline, shallow=False): | |
| sys.exit('{} is out of date; regenerate with a writable source tree'.format(baseline)) |