File: generate_iwyu_mapping_cppwinrt.py

package info (click to toggle)
monado 25.0.0%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 22,708 kB
  • sloc: cpp: 175,132; ansic: 141,570; python: 2,913; java: 753; xml: 735; sh: 403; javascript: 255; makefile: 58
file content (65 lines) | stat: -rw-r--r-- 2,007 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#!/usr/bin/env python3
# Copyright 2022-2023, Collabora, Ltd.
#
# SPDX-License-Identifier: BSL-1.0
#
# Original author: Rylie Pavlik <rylie.pavlik@collabora.com
"""Script to set up cppwinrt.imp for include-what-you-use."""
from pathlib import Path
import sys
import re
from generate_iwyu_mapping import write_mapping_file

_SCRIPT_DIR = Path(__file__).parent.resolve()
_OUTPUT_FILENAME = _SCRIPT_DIR / "cppwinrt.imp"

header_guard = re.compile(r"#ifndef WINRT_([a-zA-Z0-9_]+)_H\s*")


def find_namespace_name(header: Path) -> str:
    with open(header, "r", encoding="utf-8") as fp:
        for line in fp:
            result = header_guard.match(line)
            if not result:
                continue
            define_insides = result.group(1)
            return define_insides.replace("_", ".")

    raise RuntimeError("Could not figure out namespace name for " + str(header))


def make_canonical_include(namespace_name: str) -> str:
    return "<winrt/%s.h>" % namespace_name


def make_private_include_pattern(namespace_name: str) -> str:
    def munge_character(c: str):
        if c == ".":
            return "[.]"
        if c.isupper():
            return "[%s%s]" % (c, c.lower())
        return c

    munged_namespace = "".join(munge_character(c) for c in namespace_name)
    return "@<winrt/impl/%s[.][0-9][.]h>" % munged_namespace


def get_all_cppwinrt_entries(cppwinrt_root: str):
    root = Path(cppwinrt_root)
    for header in root.glob("*.h"):
        namespace_name = find_namespace_name(header)
        pattern = make_private_include_pattern(namespace_name)
        canonical = make_canonical_include(namespace_name)
        yield """{ include: ["%s", "private", "%s", "public"] },""" % (
            pattern,
            canonical,
        )


def write_file(cppwinrt_root: str):
    entries = list(get_all_cppwinrt_entries(cppwinrt_root))
    write_mapping_file(entries, _OUTPUT_FILENAME, Path(__file__).resolve().name)


if __name__ == "__main__":
    write_file(sys.argv[1])