The open source OpenXR runtime
1#!/usr/bin/env python3
2# Copyright 2022-2023, Collabora, Ltd.
3#
4# SPDX-License-Identifier: BSL-1.0
5#
6# Original author: Rylie Pavlik <rylie.pavlik@collabora.com
7"""Script to set up cppwinrt.imp for include-what-you-use."""
8from pathlib import Path
9import sys
10import re
11from generate_iwyu_mapping import write_mapping_file
12
13_SCRIPT_DIR = Path(__file__).parent.resolve()
14_OUTPUT_FILENAME = _SCRIPT_DIR / "cppwinrt.imp"
15
16header_guard = re.compile(r"#ifndef WINRT_([a-zA-Z0-9_]+)_H\s*")
17
18
19def find_namespace_name(header: Path) -> str:
20 with open(header, "r", encoding="utf-8") as fp:
21 for line in fp:
22 result = header_guard.match(line)
23 if not result:
24 continue
25 define_insides = result.group(1)
26 return define_insides.replace("_", ".")
27
28 raise RuntimeError("Could not figure out namespace name for " + str(header))
29
30
31def make_canonical_include(namespace_name: str) -> str:
32 return "<winrt/%s.h>" % namespace_name
33
34
35def make_private_include_pattern(namespace_name: str) -> str:
36 def munge_character(c: str):
37 if c == ".":
38 return "[.]"
39 if c.isupper():
40 return "[%s%s]" % (c, c.lower())
41 return c
42
43 munged_namespace = "".join(munge_character(c) for c in namespace_name)
44 return "@<winrt/impl/%s[.][0-9][.]h>" % munged_namespace
45
46
47def get_all_cppwinrt_entries(cppwinrt_root: str):
48 root = Path(cppwinrt_root)
49 for header in root.glob("*.h"):
50 namespace_name = find_namespace_name(header)
51 pattern = make_private_include_pattern(namespace_name)
52 canonical = make_canonical_include(namespace_name)
53 yield """{ include: ["%s", "private", "%s", "public"] },""" % (
54 pattern,
55 canonical,
56 )
57
58
59def write_file(cppwinrt_root: str):
60 entries = list(get_all_cppwinrt_entries(cppwinrt_root))
61 write_mapping_file(entries, _OUTPUT_FILENAME, Path(__file__).resolve().name)
62
63
64if __name__ == "__main__":
65 write_file(sys.argv[1])